[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Question about if in Ruby

John Joyce

3/23/2007 11:38:00 AM

I've seen this in Rails, but it is just ERb, so it is Ruby...


<%= link_to 'Previous page', { :page =>
@product_pages.current.previous } if @product_pages.current.previous %>


I'm curious how it is different from this...


<%= if @product_pages.current.previous link_to ('Previous page',
{ :page => @product_pages.current.previous })
end
%>


I've seen this kind of if statement reversal a few times now in Ruby
code. I call it do-if because it looks similar to do-while, but I am
curious if reversing the condition affects the interpreter's speed at
all. If they are the same, then isn't the standard if conditional
better for human legibility and understanding?

14 Answers

Vince H&K

3/23/2007 11:53:00 AM

0

John Joyce wrote:
> I've seen this in Rails, but it is just ERb, so it is Ruby...
>
>
> <%= link_to 'Previous page', { :page => @product_pages.current.previous
> } if @product_pages.current.previous %>
>
>
> I'm curious how it is different from this...
>
>
> <%= if @product_pages.current.previous link_to ('Previous page', {
> :page => @product_pages.current.previous })
> end
> %>
>
>
> I've seen this kind of if statement reversal a few times now in Ruby
> code. I call it do-if because it looks similar to do-while, but I am
> curious if reversing the condition affects the interpreter's speed at
> all. If they are the same, then isn't the standard if conditional better
> for human legibility and understanding?

The first form of the statement is valid for only one instruction. Both

if something
do_something
end

and

do_something if something

are equivalent, but when it comes to

if a
one_thing
another_thing
end

you simply can't use the other form, as it applies to only one instruction.

The whole thing about this is readability. Depending on the cases and
your personal tastes, it will look more logical to use one form or
another (for one instruction). What is great in Ruby (IMHO), is that you
have many ways to express the same things, some of them quite verbose,
which means you can write code sometimes nearly as readable as pure
English text.

Cheers,

Vince



--
Vincent Fourmond, PhD student (not for long anymore)
http://vincent.fourmon...

John Joyce

3/23/2007 12:15:00 PM

0

Thanks Vince!
That's precisely what I wanted to know.
I had seen a few cases where the conditional coming later did make
sense as an English sentence. I've seen unless used in a similar way.
It does read well (after knowing some of the Ruby of course.)

dblack

3/23/2007 12:59:00 PM

0

Hi --

On 3/23/07, Vince H&K <vince.hetk@gmail.com> wrote:
> John Joyce wrote:
> > I've seen this in Rails, but it is just ERb, so it is Ruby...
> >
> >
> > <%= link_to 'Previous page', { :page => @product_pages.current.previous
> > } if @product_pages.current.previous %>
> >
> >
> > I'm curious how it is different from this...
> >
> >
> > <%= if @product_pages.current.previous link_to ('Previous page', {
> > :page => @product_pages.current.previous })
> > end
> > %>
> >
> >
> > I've seen this kind of if statement reversal a few times now in Ruby
> > code. I call it do-if because it looks similar to do-while, but I am
> > curious if reversing the condition affects the interpreter's speed at
> > all. If they are the same, then isn't the standard if conditional better
> > for human legibility and understanding?
>
> The first form of the statement is valid for only one instruction. Both
>
> if something
> do_something
> end
>
> and
>
> do_something if something
>
> are equivalent, but when it comes to
>
> if a
> one_thing
> another_thing
> end
>
> you simply can't use the other form, as it applies to only one instruction.

Just for completeness (I'm not recommending it), I'll mention that you can do:

one_thing if begin
another_thing
a_third_thing
end


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning...)
(See what readers are saying! http://www.r.../r...)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.r...)

John Joyce

3/23/2007 1:47:00 PM

0


On Mar 23, 2007, at 9:59 PM, David A. Black wrote:
>
> Just for completeness (I'm not recommending it), I'll mention that
> you can do:
>
> one_thing if begin
> another_thing
> a_third_thing
> end
>
>
> David

Completeness is good. But that is pretty hideous stuff.
Starting to look like some cryptic C or ambitious BASIC:
logic spaghetti.

Jeremy McAnally

3/23/2007 2:20:00 PM

0

You can also do this:

begin
one_thing
second_thing
do_more
end if true == true

-OR-

begin
one_thing
two_thing
three_thing
end if begin
another_thing
another_better_thing
end

But, of course, we're just getting ridiculous now. ;)

--Jeremy

On 3/23/07, John Joyce <dangerwillrobinsondanger@gmail.com> wrote:
>
> On Mar 23, 2007, at 9:59 PM, David A. Black wrote:
> >
> > Just for completeness (I'm not recommending it), I'll mention that
> > you can do:
> >
> > one_thing if begin
> > another_thing
> > a_third_thing
> > end
> >
> >
> > David
>
> Completeness is good. But that is pretty hideous stuff.
> Starting to look like some cryptic C or ambitious BASIC:
> logic spaghetti.
>
>


--
http://www.jeremymca...

My free Ruby e-book:
http://www.humblelittlerubybook...

My blogs:
http://www.mrneigh...
http://www.rubyinpra...

dblack

3/23/2007 3:54:00 PM

0

Hi --

On 3/23/07, John Joyce <dangerwillrobinsondanger@gmail.com> wrote:
>
> On Mar 23, 2007, at 9:59 PM, David A. Black wrote:
> >
> > Just for completeness (I'm not recommending it), I'll mention that
> > you can do:
> >
> > one_thing if begin
> > another_thing
> > a_third_thing
> > end
> >
> >
> > David
>
> Completeness is good. But that is pretty hideous stuff.
> Starting to look like some cryptic C or ambitious BASIC:
> logic spaghetti.

I wouldn't worry too much:

$ find . -name "*.rb" -exec grep "if begin" '{}' ';' | wc -l
0

:-)


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning...)
(See what readers are saying! http://www.r.../r...)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.r...)

Robert Klemme

3/23/2007 4:04:00 PM

0

On 23.03.2007 16:53, David A. Black wrote:
> Hi --
>
> On 3/23/07, John Joyce <dangerwillrobinsondanger@gmail.com> wrote:
>>
>> On Mar 23, 2007, at 9:59 PM, David A. Black wrote:
>> >
>> > Just for completeness (I'm not recommending it), I'll mention that
>> > you can do:
>> >
>> > one_thing if begin
>> > another_thing
>> > a_third_thing
>> > end
>> >
>> >
>> > David
>>
>> Completeness is good. But that is pretty hideous stuff.
>> Starting to look like some cryptic C or ambitious BASIC:
>> logic spaghetti.
>
> I wouldn't worry too much:
>
> $ find . -name "*.rb" -exec grep "if begin" '{}' ';' | wc -l
> 0
>
> :-)

Same here:

17:02:44 [~]: ruby -e 'puts Dir["/usr/lib/ruby/**/*.rb"].inject(0)
{|c,f| /if\s+begin/ =~ File.read(f) ? c+1 : c}'
0
17:03:10 [~]:

:-)

robert

Trans

3/24/2007 11:53:00 AM

0



On Mar 23, 7:53 am, Vince H&K <vince.h...@gmail.com> wrote:
> John Joyce wrote:
> > I've seen this in Rails, but it is just ERb, so it is Ruby...
>
> > <%= link_to 'Previous page', { :page => @product_pages.current.previous
> > } if @product_pages.current.previous %>
>
> > I'm curious how it is different from this...
>
> > <%= if @product_pages.current.previous link_to ('Previous page', {
> > :page => @product_pages.current.previous })
> > end
> > %>
>
> > I've seen this kind of if statement reversal a few times now in Ruby
> > code. I call it do-if because it looks similar to do-while, but I am
> > curious if reversing the condition affects the interpreter's speed at
> > all. If they are the same, then isn't the standard if conditional better
> > for human legibility and understanding?
>
> The first form of the statement is valid for only one instruction. Both
>
> if something
> do_something
> end
>
> and
>
> do_something if something
>
> are equivalent, but when it comes to
>
> if a
> one_thing
> another_thing
> end
>
> you simply can't use the other form, as it applies to only one instruction.


There is one other difference.

if a = 1
p a
end

p a if a = 1

The later does not assign the a.

btw you can also use parens for more than one call.


( do_this ; do_that ) if something

or

( do_this
do_that
) if something


T.


Vince H&K

3/24/2007 12:05:00 PM

0

Trans wrote:
> There is one other difference.
>
> if a = 1
> p a
> end
>
> p a if a = 1
>
> The later does not assign the a.

This is not exactly true (at least on ruby 1.8.6):

irb(main):001:0> if a = 1
irb(main):002:1> p a
irb(main):003:1> end
1
=> nil
irb(main):004:0> p b if b = 2
NameError: undefined local variable or method `b' for main:Object
from (irb):4
from :0

It doesn't create the variable b in the same scope as the one of the
instruction. However:

irb(main):007:0> a = 1
=> 1
irb(main):008:0> p a if a = 2
2
=> nil
irb(main):009:0> a
=> 2

It does assign it if it already exists in the current scope. Works as
well in ruby (it is not an irb artifact).

Cheers,

Vince

--
Vincent Fourmond, PhD student (not for long anymore)
http://vincent.fourmon...

Rick DeNatale

3/26/2007 10:11:00 PM

0

On 3/24/07, Vince H&K <vince.hetk@gmail.com> wrote:
> Trans wrote:
> > There is one other difference.
> >
> > if a = 1
> > p a
> > end
> >
> > p a if a = 1
> >
> > The later does not assign the a.
>
> This is not exactly true (at least on ruby 1.8.6):
>
> irb(main):001:0> if a = 1
> irb(main):002:1> p a
> irb(main):003:1> end
> 1
> => nil
> irb(main):004:0> p b if b = 2
> NameError: undefined local variable or method `b' for main:Object
> from (irb):4
> from :0
>
> It doesn't create the variable b in the same scope as the one of the
> instruction. However:
>
> irb(main):007:0> a = 1
> => 1
> irb(main):008:0> p a if a = 2
> 2
> => nil
> irb(main):009:0> a
> => 2
>
> It does assign it if it already exists in the current scope. Works as
> well in ruby (it is not an irb artifact).

In fact it DOES assign:
rick@frodo:/public/rubysource/ruby1.8.5$ irb
irb(main):001:0> a
NameError: undefined local variable or method `a' for main:Object
from (irb):1
irb(main):002:0> p a if a = 1
(irb):2: warning: found = in conditional, should be ==
NameError: undefined local variable or method `a' for main:Object
from (irb):2
irb(main):003:0> a
=> 1


I think that it's more accurate to say that the difference between

if a = 1
...
end

and

... if a = 1

is that the latter checks for the existence of a and raises a
NameError after the assignment if the variable didn't exist before.

Is this a bug? Maybe. It is kind of an edge case, notice the warning
indicating that you really should be using a comparison instead of an
assignment.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...