Understanding the use of double pipes in Ruby

Hi,

Can someone explain the use of double pipes “||” in Ruby?
Are these part of blocks only?
Where else can double pipes be used besides in a block and as the OR
symbol?

The way I understand it, is basically for adding temporary variables to
help identify items in an array, other than that I’m not sure
where else can they be used.

Thanks a lot!

On Tue, Nov 8, 2011 at 7:27 AM, Fily S. [email protected] wrote:

Thanks a lot!


Posted via http://www.ruby-forum.com/.

The most obvious thing you can do is a logical “or”

true || false
ticketed = speed_limit < speed || flips_off_the_cops

They can also be used for things that take arbitrary delimiters such as
the
various % ways of defining literals

%|a b c| # => “a b c”
%w|a b c| # => [“a”, “b”, “c”]

On Tue, Nov 8, 2011 at 08:27, Fily S. [email protected] wrote:

Can someone explain the use of double pipes “||” in Ruby?

It’s the logical “or” operator.

Are these part of blocks only?

The pipes that surround block arguments are a different beastie
entirely.

Where else can double pipes be used?

Mainly in combining boolean values. Say you want to do something if
some number is not in the positive two-digit range (leading zeroes
don’t count). You would do:

if mynum < 10 || mynum > 100
# do whatever
end

The way I understand it, is basically for adding temporary variables to
help identify items in an array, other than that I’m not sure
where else can they be used.

That’s not the main usage, it’s just a handy trick. When you see the
construction:

arr[x] ||= y

what that’s really saying is “evaluate arr[x], and if that’s false
(which could be either the actual boolean value of false, or it could
be nil, such as if no value was assigned there), put y there, else
leave it alone”. Despite the usual meaning of tacking an = sign onto
any operator, it’s not quite equivalent to:

arr[x] = arr[x] || y

which will perform an assignment in either case. The previous one
will not, if arr[x] already had a (non-false) value. IIRC, one of the
popular Ruby podcasts recently covered a recent post about this on one
of the popular Ruby blogs. In trying to remember it I’m hearing it in
Peter C.'s voice so it was probably on The Ruby Show, but I don’t
think it was his blog, maybe Virtuous Code by Avdi G…

Alternately you might see:

x = y || z

This could be boolean math, or it could be “if y is not false (or
nil) assign it to x, else assign z to x”.

You might be getting confused because Ruby also has “and” and “or”
keywords, but these are subtly different, suitable only for use in
boolean manipulation, and usually better off forgotten.

-Dave

First of all thank a lot for your help!

Sorry about the confusion, I was talking more about pipes used in a
block something like “|hobby|” in the code below.

hobbies =[‘Cars’,‘Computers’]
hobbies.each do |hobby|

puts “I love working with #{hobby}”
end

Is this the only time where “||” will not act as a boolean symbol? If
this is a local variable why not use paranthesis as follow…

hobbies =[‘Cars’,‘Computers’]
hobbies.each do (hobby)

puts “I love working with #{hobby}”
end

Again my main confusion is because I have never seen double pipes used
other than as Booleans, why are they used to enclose a local variable?

Sorry if I’m still confusing or not explaining it correclty.

Ok, it looks like this is a completely different animal that belongs to
the block it self.

Thanks a lot for your help.

On Tue, Nov 8, 2011 at 10:22, Fily S. [email protected] wrote:

Sorry about the confusion, I was talking more about pipes used in a
block something like “|hobby|” in the code below.

hobbies.each do |hobby|

Oh! That’s different. I thought you mainly meant the ||= trick.

Is this the only time where “||” will not act as a boolean symbol?

As someone else pointed out, there are some times when Ruby will let
you use pretty much anything as delimiters, but even then:

If this is a local variable why not use paranthesis as follow…

hobbies.each do (hobby)

If Ruby allowed us to use arbitrary delimeters here, parens wouldn’t
work because they don’t match. That is, the opener is different from
the closer. Arbitrary delimiters might let you do something like
“hobbies.each do (hobby(”, but that would be even worse. :slight_smile:

You’re right that introducing a new syntax for what are essentially
arguments, adds a bit more to what a newbie needs to learn. Parens
would make it more obvious. I suspect that one reason parens aren’t
used there, is that you can often omit the block args if they’re not
going to be used, and parens could look like an expression that you
want evaluated.

Again my main confusion is because I have never seen double pipes used
other than as Booleans, why are they used to enclose a local variable?

Don’t think of it as double pipes, just think of it as two single
pipes. And don’t get started on applying them as bit-wise ORs. :wink:

-Dave