Translate Perl diamond operator to Ruby

Over the years, I’ve found the following to be an excellent way to whip
up quick, very useful Perl scripts:

#!/usr/bin/perl

while(<>) {
# do stuff . . .
}

Is there an equivalent idiom in Ruby? So far as I’m aware, there’s no
catch-all diamond operator in Ruby that allows one to create a default
input behavior for a script that accepts either a filename or piped
output of another command the way this works in Perl. I certainly hope
there’s an equivalent, though.

Curious +1

:slight_smile:

On Mon, 16 Apr 2007 03:06:58 +0900, Chad P. wrote:

catch-all diamond operator in Ruby that allows one to create a default
input behavior for a script that accepts either a filename or piped
output of another command the way this works in Perl. I certainly hope
there’s an equivalent, though.

ARGF.each do |line|

do stuff

end

On 15 Apr 2007, at 19:40, Ken B. wrote:

}
ARGF.each do |line|

do stuff

end

What is ARGF? I’ve printed it’s class, but apparently it is:

irb(main):003:0> ARGF.class
=> Object

… an Object.

On Mon, Apr 16, 2007 at 03:06:58AM +0900, Chad P. wrote:

catch-all diamond operator in Ruby that allows one to create a default
input behavior for a script that accepts either a filename or piped
output of another command the way this works in Perl. I certainly hope
there’s an equivalent, though.

while gets

do stuff with $_

end

Or, less perly,

while line = gets

do stuff with line

end

Or, if there are multiple files listed on ARGV, and you want to slurp
them
all one at a time,

while contents = gets(nil)

do stuff with contents

end

Doing that in Perl seems quite hard.

B.

On Mon, Apr 16, 2007 at 05:27:24AM +0900, Benjohn B. wrote:

What is ARGF? I’ve printed it’s class, but apparently it is:

irb(main):003:0> ARGF.class
=> Object

… an Object.

Now that I know ARGF exists . . .

http://www.danvk.org/wp/?m=200701 reports the following:

ARGF is a great crutch for Perl programmers who miss typing while(<>)
{…}. It opens each input file left in ARGV and yields each line. If
there´s no input files left, it reads STDIN and yields each line it
gets there. Many, many programs do their work in an ARGF loop.

On Mon, Apr 16, 2007 at 03:40:17AM +0900, Ken B. wrote:

Is there an equivalent idiom in Ruby? So far as I’m aware, there’s no
catch-all diamond operator in Ruby that allows one to create a default
input behavior for a script that accepts either a filename or piped
output of another command the way this works in Perl. I certainly hope
there’s an equivalent, though.

ARGF.each do |line|

do stuff

end

Thanks muchly. Armed with this seed of knowledge (to mix a metaphor), I
can find the rest via Google easily. I appreciate it.

On Apr 15, 2007, at 3:25 PM, Brian C. wrote:

Or, less perly,

while line = gets

do stuff with line

end

I really feel the Ruby version is to use a standard iterator:

ARGF.each do |line|

do stuff with line

end

Or, if there are multiple files listed on ARGV, and you want to
slurp them
all one at a time,

while contents = gets(nil)

do stuff with contents

end

contents = ARGF.read

James Edward G. II

On Mon, Apr 16, 2007 at 05:25:41AM +0900, Brian C. wrote:

while contents = gets(nil)

do stuff with contents

end

Doing that in Perl seems quite hard.

Thanks for the information. As for this last example, the functionality
you achieved isn’t exactly “hard” in Perl, but it’s a touch less
intuitive. Slurping a file via the diamond operator should end up
looking something like this, generally:

my $foo;
{ local $/; $foo = <>; }

The “my $foo” part, for those not familiar with Perl, is just the way
the $foo variable can be declared with lexical scope. If you’re writing
code without strict and warnings pragmas (indispensable debugging aids
in Perl), you could dispense with the “my $foo” line altogether.

In fact, you could dispense with the braces and use “undef $/” instead
of “local $/” if you prefer, as long as you don’t care about getting the
original value of $/ back (or want to put it back in manually for some
reason).

TIMTOWTDI.

On Mon, Apr 16, 2007 at 12:18:12PM +0900, James Edward G. II wrote:

gets there. Many, many programs do their work in an ARGF loop.

I don’t much care for that description. ARGF simplifies the
implementation of some very common behavior for command-line
programs. I don’t feel it exists merely as a crutch for Perl
programmers.

Nor do I. I found the more implementation-related description to be
somewhat useful, however, once I got past the opining.

On Apr 15, 2007, at 5:07 PM, Chad P. wrote:

Now that I know ARGF exists . . .

http://www.danvk.org/wp/?m=200701 reports the following:

ARGF is a great crutch for Perl programmers who miss typing while
(<>)
{…}. It opens each input file left in ARGV and yields each
line. If
there´s no input files left, it reads STDIN and yields each line it
gets there. Many, many programs do their work in an ARGF loop.

I don’t much care for that description. ARGF simplifies the
implementation of some very common behavior for command-line
programs. I don’t feel it exists merely as a crutch for Perl
programmers.

James Edward G. II

On 16.04.2007 00:08, Chad P. wrote:

}
Thanks muchly. Armed with this seed of knowledge (to mix a metaphor), I
can find the rest via Google easily. I appreciate it.

You can also use one of the command line switches -n or -p, e.g.

13:04:42 [tmp]: ls -l | ruby -ne ‘puts “<#{$_[0,3]}>”’

<-rw>

13:04:59 [tmp]:

Kind regards

robert

On Mon, Apr 16, 2007 at 08:05:05PM +0900, Robert K. wrote:

do stuff . . .

Kind regards

robert

That’s useful, and very similar to Perl, but in practice I find that I
don’t take that approach very often at all. The only command/shebang
line switch I use with any frequency in Perl is -l, for adding a newline
to the end of all print statements, and since Ruby has puts I don’t need
to do that in Ruby. Usually, the programs I find myself writing don’t
neatly fit into a while loop – except when writing a toy script to
demonstrate something, in which case it usually pays to be explicit with
the while loop anyway – so the while (<>) { . . . } idiom in Perl (and
now the ARGF.each do |foo| . . . end idiom in Ruby) is far more useful
to me.