╦ ╦╦╔╗╔╦╔═╦╔╗╔╔═╗ ║║║║║║║╠╩╗║║║║║ ╦ ╚╩╝╩╝╚╝╩ ╩╩╝╚╝╚═╝ ╔═╗╔═╗╔╦╗ ╔═╗╔═╗╔╦╗╔╦╗╔═╗ ╠╣ ╠═╣ ║ ║ ║ ║║║║║║║╠═╣ ╚ ╩ ╩ ╩ ╚═╝╚═╝╩ ╩╩ ╩╩ ╩ ╔═╗╔═╗╔═╗╦═╗╔═╗╔╦╗╔═╗╦═╗ ║ ║╠═╝║╣ ╠╦╝╠═╣ ║ ║ ║╠╦╝ ╚═╝╩ ╚═╝╩╚═╩ ╩ ╩ ╚═╝╩╚═ ============================================================================ Filehandles in Perl are weird. Opening a file for output: open(my $fh, '>', $filename); That > is a mode indicator. But what if $filename starts with >? open(my $fh, '>', '>dangerous'); Does that open a file called ">dangerous" or append to "dangerous"? Enter the winking fat comma: +> Filehandle protection. A mode indicator that can't be confused. ============================================================================ PART 1: THE PROBLEM ------------------- Two-argument open is dangerous: open(FH, $file); If $file is "> /etc/passwd", you've just clobbered your password file. Three-argument open is safer: open(my $fh, '<', $file); The mode is separate from the filename. But even here, weird filenames can cause issues or confusion. ============================================================================ PART 2: THE SOLUTION -------------------- Prefix the mode with +: open(my $fh, '+>', $filename); # Read-write, truncate open(my $fh, '+<', $filename); # Read-write, preserve Wait, that's just read-write mode. Where's the winking fat comma? The "winking fat comma" is actually using +> (or +<) to make your intentions crystal clear, especially in ambiguous situations: open(my $fh, '+<', '>weird'); # Opens file literally named ">weird" .--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/ ============================================================================ PART 3: ACTUALLY, LET'S BE HONEST --------------------------------- The "winking fat comma" is one of the more obscure entries in the secret operators list. The term refers to using +> in places where you want to emphasize that the > is a mode, not part of a filename. open(my $fh, "+>", $file); The + "winks" at you, saying "this > is definitely a mode indicator." It's more about documentation and clarity than functionality. ============================================================================ PART 4: THE REAL LESSON ----------------------- Always use three-argument open: open(my $fh, '<', $filename) or die "Can't read $filename: $!"; open(my $fh, '>', $filename) or die "Can't write $filename: $!"; open(my $fh, '>>', $filename) or die "Can't append $filename: $!"; The mode and filename are separate. No ambiguity. The + modes add read-write capability: +< Read-write, file must exist, preserve contents +> Read-write, create/truncate file ============================================================================ PART 5: DANGEROUS FILENAMES --------------------------- Files that could cause problems: >file Looks like output redirect file| Looks like pipe |command Looks like command - Looks like STDIN Three-argument open handles all of these: my $scary = "|rm -rf /"; open(my $fh, '<', $scary); # Opens literal file, not a pipe The < forces read mode. The filename is just a filename. ============================================================================ PART 6: THE FAT COMMA ITSELF ---------------------------- While we're here, the actual "fat comma": => It's called fat because it's wider than a regular comma. And it auto-quotes the left side: my %hash = ( key => 'value', # 'key' is auto-quoted foo => 'bar', ); Same as: my %hash = ( 'key', 'value', 'foo', 'bar', ); ============================================================================ PART 7: THE WINK ---------------- So why "winking fat comma"? +> + Looks like a cross or plus sign > Looks like... greater than? Arrow? Together: +> If you squint and tilt your head: +> \ O <- that's the wink? Honestly, this one's a stretch. The Perl community loves naming things, and sometimes the names are more memorable than meaningful. ============================================================================ PART 8: PRACTICAL USAGE ----------------------- When you actually use +> in real code: # Create a temp file, read and write open(my $tmp, '+>', undef) or die "Can't create temp: $!"; print $tmp "data\n"; seek($tmp, 0, 0); my $content = <$tmp>; The undef as filename creates an anonymous temp file. # Read-write an existing file open(my $fh, '+<', 'config.txt') or die "Can't open: $!"; my @lines = <$fh>; seek($fh, 0, 0); truncate($fh, 0); print $fh @modified_lines; Read, modify, write back. ============================================================================ PART 9: THE MODES CHEAT SHEET ----------------------------- MODE READ WRITE CREATE TRUNCATE POSITION ------------------------------------------------------- < Yes No No No Start > No Yes Yes Yes Start >> No Yes Yes No End +< Yes Yes No No Start +> Yes Yes Yes Yes Start +>> Yes Yes Yes No End The + adds read capability to write modes (and vice versa). ============================================================================ PART 10: THE HONEST ASSESSMENT ------------------------------ Look, the "winking fat comma" isn't really a thing in the same way that the goatse operator or butterfly operator are things. It's more of an entry in the secret operators catalog that makes people go "huh, I guess you could call it that." The real takeaway: use three-argument open. Always. And understand the + modes for read-write operations. ============================================================================ PART 11: ACTUALLY USEFUL THINGS ------------------------------- If you're here for filehandle protection, here's what matters: # ALWAYS use three-argument open open(my $fh, '<', $file) or die "Can't open $file: $!"; # ALWAYS use lexical filehandles (my $fh) # Not barewords (FH) which are global # ALWAYS check for errors # or die, or use autodie use autodie; # Now all opens die on failure automatically That's the real secret. Not the winking fat comma. ============================================================================ PART 12: THE NAME EXPLAINED --------------------------- Fat comma: => Winking: adding + to make +> or +< Together: winking fat comma It's a play on words. The + is the wink. The > or < after it makes it look like the fat comma's cousin. => Fat comma +> Winking fat comma (allegedly) The Perl community enjoys whimsical naming. This one's just not as clever as the others. ============================================================================ +> / \ + > / \ wink arrow More cute than useful, honestly ============================================================================ japh.codes