ARGF: The Diamond Operator on Steroids
ARGF is Ruby's equivalent of Perl's diamond operator<>. It automatically reads from files listed in ARGV, or from STDIN if no files are given. But here's the thing: it's actually MORE powerful than Perl's version. If that doesn't get your attention, you might be reading the wrong blog.
Part 1: The Perl Translation
# Perl: read from files or stdin while (<>) { print if /pattern/; }
Same behavior. Different syntax. Both read from filenames passed on the command line, or from STDIN if no files are given.# Ruby: identical behavior ARGF.each_line do |line| puts line if line =~ /pattern/ end
Part 2: Basic Usage
# These are all equivalent: $<.each_line { |l| puts l } ARGF.each_line { |l| puts l } # Run with: # ruby script.rb file1.txt file2.txt (reads both files) # cat file.txt | ruby script.rb (reads stdin) # ruby script.rb (waits for stdin)
Part 3: ARGF Methods
Reading lines one at a time:Slurping entire input into one string:ARGF.each_line do |line| # process each line from all input files/stdin end # Or read all lines at once all_lines = ARGF.readlines
Getting the current filename:# Read everything into one string content = ARGF.read # Equivalent one-liner: ruby -0777 -ne 'puts $_.length' file.txt
Skipping to next file (this is where ARGF flexes on Perl):ARGF.each_line do |line| puts "#{ARGF.filename}:#{ARGF.lineno}: #{line}" end
ARGF.each_line do |line| if line =~ /SKIP_THIS_FILE/ ARGF.skip # Move to next file in ARGV next end puts line end
Part 4: ARGF vs Perl's Diamond Operator
| Feature | Perl <> |
Ruby ARGF |
|---|---|---|
| Read from files/stdin | Yes | Yes |
| Current filename | $ARGV |
ARGF.filename |
| Line number | $. |
ARGF.lineno or $. |
| Skip to next file | close ARGV |
ARGF.skip |
| Read all at once | local $/; <> |
ARGF.read |
| Get all lines | my @lines = <> |
ARGF.readlines |
| Binary read | Via read |
ARGF.binmode; ARGF.read |
ARGF.skip is a lot clearer than close ARGV.
Part 5: Practical One-Liners
# Grep across multiple files with filename ruby -ne 'puts "#{$FILENAME}:#{$.}: #{$_}" if /ERROR/' *.log # Count total lines across all input files ruby -ne 'END { puts $. }' file1.txt file2.txt # Cat with line numbers (like cat -n) ruby -ne 'printf "%6d %s", $., $_' file.txt
Part 6: The -n and -p Connection
When you use-n or -p switches, Ruby wraps your code in an ARGF loop automatically:
The# ruby -ne 'CODE' is equivalent to: while gets CODE end # ruby -pe 'CODE' is equivalent to: while gets CODE print $_ end
gets method reads from ARGF by default, which is why -n and -p automatically handle files and stdin. ARGF is always there, quietly doing the work.
Created By: Wildcard Wizard. Copyright 2026