[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Is Assignment in a Conditional an Idiom?

worthee

10/2/2008 6:36:00 PM

Hi

I was just reading the following blog post
http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
and like the author, it is the first time I have seen code as he
describes. From the comments it would seem that some think it is an
idiom to be used, and perhaps others do not.

Just curious as to how common this use it? I do tend to side with
view that it is not clear at first glance.

Thanks
Richard
20 Answers

Robert Dober

10/2/2008 6:56:00 PM

0

On Thu, Oct 2, 2008 at 8:38 PM, <worthee@gmail.com> wrote:
> Hi
>
> I was just reading the following blog post
> http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
> and like the author, it is the first time I have seen code as he
> describes. From the comments it would seem that some think it is an
> idiom to be used, and perhaps others do not.
>
> Just curious as to how common this use it? I do tend to side with
> view that it is not clear at first glance.
>
> Thanks
> Richard
>
>

It seems very bad code to me, what is wrong with the following?
@attributes['comments'] =3D @attributes['comments'].split( " " )
rescue @attributes['comments']
although I suspect that
... @attributes['comments'].split ...
is what the good fellow really wants.

HTH
Robert


--=20
C'est v=E9ritablement utile puisque c'est joli.

Antoine de Saint Exup=E9ry

Trans

10/2/2008 7:14:00 PM

0



On Oct 2, 2:38=A0pm, wort...@gmail.com wrote:
> Hi
>
> I was just reading the following blog posthttp://www.elctech.com...
rity-over-cleverness-but-what-is-clever,
> and like the author, it is the first time I have seen code as he
> describes. =A0From the comments it would seem that some think it is an
> idiom to be used, and perhaps others do not.
>
> Just curious as to how common this use it? =A0I do tend to side with
> view that it is not clear at first glance.

It's pretty common; since it saves a line of code. As long as the
assignment is right on the surface of the condition, and not buried
deep inside other logic, I think it works well and is quite readable.

IMHO,
T.

Trans

10/2/2008 7:21:00 PM

0



On Oct 2, 2:55=A0pm, "Robert Dober" <robert.do...@gmail.com> wrote:
> On Thu, Oct 2, 2008 at 8:38 PM, =A0<wort...@gmail.com> wrote:
> > Hi
>
> > I was just reading the following blog post
> >http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
> > and like the author, it is the first time I have seen code as he
> > describes. =A0From the comments it would seem that some think it is an
> > idiom to be used, and perhaps others do not.
>
> > Just curious as to how common this use it? =A0I do tend to side with
> > view that it is not clear at first glance.
>
> > Thanks
> > Richard
>
> It seems very bad code to me, what is wrong with the following?
> =A0 =A0@attributes['comments'] =3D @attributes['comments'].split( " " )
> rescue @attributes['comments']
> although I suspect that
> =A0 =A0 =A0 =A0 =A0... @attributes['comments'].split ...
> is what the good fellow really wants.

I wouldn't recommend that. Rule of thumb, don't use rescue when a
regular condition does the job.

Also one must consider if there is a difference between key presence
and key returning nil. In which case it may be better to use:

if @attributes.key?('comments')

T.


Robert Klemme

10/2/2008 8:39:00 PM

0

On 02.10.2008 20:35, worthee@gmail.com wrote:
> I was just reading the following blog post
> http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
> and like the author, it is the first time I have seen code as he
> describes. From the comments it would seem that some think it is an
> idiom to be used, and perhaps others do not.
>
> Just curious as to how common this use it? I do tend to side with
> view that it is not clear at first glance.

I believe this is a bad idiom. First, the test for "comments" is not
needed because "String === comments" will be false if "comments" is nil.
The statement would have been written much clearer as

comments = @attributes['comments'])

if comments.is_a? String
@attributes['comments'] = comments.split(" ")
end

or

comments = @attributes['comments'])
@attributes['comments'] = comments.split(" ") if comments.is_a? String

or

comments = @attributes['comments'])
@attributes['comments'] = comments.split(" ") if String === comments

There is only one situation where assignment in a conditional actually
makes code clearer and that is with loops, e.g.

while line = io.gets
puts line
end

My 0.02EUR

Kind regards

robert

list. rb

10/3/2008 6:22:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Awesome!
For the record, this is the code mentioned in the blog:

1 if (comments = @attributes['comments']) &&
comments.is_a?(String) 2 @attributes['comments'] =
comments.split(" ") 3 end


I never knew it was possible to define a variable from within a condition.
Goes to show you that ruby offers plenty of rope to hang yourself if you are
not careful. Correction -I have accidentally done it in the past and never
viewed it as a feature until now.

One thing I found intriguing, was how the conditions were looking at the
response from the definition, not the value of the variable being defined.
That makes sense in thinking about it but

For example, in IRB the second line yields false:
irb(main):001:0> (a = nil)
=> nil
irb(main):002:0> (!a = a)
=> true

However neither of these two yield true in a conditional:
puts "you wont see this" unless (a = nil) or (!a = a)


I found the logistics(or lack thereof) of the example annoying. Rob is spot
on in saying being that an object of type String can never be nil. The only
excuse one could have for using this code is if they referenced the comments
variable outside of the if statement somewhere else. At which point the
comments variable could be an Array or Nil, requiring more code.

On Thu, Oct 2, 2008 at 4:38 PM, Robert Klemme <shortcutter@googlemail.com>wrote:

> On 02.10.2008 20:35, worthee@gmail.com wrote:
>
>> I was just reading the following blog post
>> http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
>> and like the author, it is the first time I have seen code as he
>> describes. From the comments it would seem that some think it is an
>> idiom to be used, and perhaps others do not.
>>
>> Just curious as to how common this use it? I do tend to side with
>> view that it is not clear at first glance.
>>
>
> I believe this is a bad idiom. First, the test for "comments" is not
> needed because "String === comments" will be false if "comments" is nil.
> The statement would have been written much clearer as
>
> comments = @attributes['comments'])
>
> if comments.is_a? String
> @attributes['comments'] = comments.split(" ")
> end
>
> or
>
> comments = @attributes['comments'])
> @attributes['comments'] = comments.split(" ") if comments.is_a? String
>
> or
>
> comments = @attributes['comments'])
> @attributes['comments'] = comments.split(" ") if String === comments
>
> There is only one situation where assignment in a conditional actually
> makes code clearer and that is with loops, e.g.
>
> while line = io.gets
> puts line
> end
>
> My 0.02EUR
>
> Kind regards
>
> robert
>
>

Pit Capitain

10/3/2008 6:43:00 AM

0

2008/10/3 list. rb <list.rb@gmail.com>:
> I found the logistics(or lack thereof) of the example annoying.

I find the results of your example very logical. What part exactly
surprised you?

Regards,
Pit

Justin Collins

10/3/2008 9:02:00 AM

0

list. rb wrote:
> Awesome!
> For the record, this is the code mentioned in the blog:
>
> 1 if (comments = @attributes['comments']) &&
> comments.is_a?(String) 2 @attributes['comments'] =
> comments.split(" ") 3 end
>
>
> I never knew it was possible to define a variable from within a condition.
> Goes to show you that ruby offers plenty of rope to hang yourself if you are
> not careful. Correction -I have accidentally done it in the past and never
> viewed it as a feature until now.
>
> <snip>

It's not really a feature of Ruby, it is common in many languages and is
also a common source of bugs and logical errors.
For example, in C/C++, assignment is always true, so in cases when you
intend to do comparison but miss the second equals sign, you end up
doing assignment. Not only is it subtle logically, it is also subtle
visually since assignment and comparison look so similar (in these
languages).
The issue is so common that if Ruby thinks you are intending to do
comparison, you will typical getting a warning: "warning: found = in
conditional, should be =="

My thoughts on the code itself is that I would not have done it that way
at all. Why even introduce a new variable unless, somehow, performance
was an issue? The overall style is not particularly 'Rubyesque" in my
opinion. I would have probably written it as:

@attributes['comments] = @attributes['comments'].split if
@attributes['comments'].is_a? String


> However neither of these two yield true in a conditional:
> puts "you wont see this" unless (a = nil) or (!a = a)
>

(!a = a) [ actually, !(a = a) ] is true, so the "puts" statement is not
executed. Maybe you meant 'if' instead of 'unless'?

-Justin

Robert Klemme

10/3/2008 9:08:00 AM

0

On 03.10.2008 08:22, list. rb wrote:
> Awesome!
> For the record, this is the code mentioned in the blog:
>
> 1 if (comments = @attributes['comments']) &&
> comments.is_a?(String) 2 @attributes['comments'] =
> comments.split(" ") 3 end

Good point. Sorry for not including this.

> I never knew it was possible to define a variable from within a condition.

Actually the picture may become simpler if you remember that there is no
distinction between statement and expression in Ruby. Every line of
code is an expression and thusly has a value. So "if a = 123" is not so
much different from "a = 123" - only in the latter case the result of
evaluating the expression is not used.

> Goes to show you that ruby offers plenty of rope to hang yourself if you are
> not careful. Correction -I have accidentally done it in the past and never
> viewed it as a feature until now.

:-) There's a lot of rope in other programming languages as well - it's
just of a different material. :-)

> One thing I found intriguing, was how the conditions were looking at the
> response from the definition, not the value of the variable being defined.

In the case of an assignment there is no difference between the two.
The result of evaluating an assignment is the new value of the variable.

One additional hint: assignment operators are evaluated right to left as
opposed to other operators.

> That makes sense in thinking about it but
>
> For example, in IRB the second line yields false:
> irb(main):001:0> (a = nil)
> => nil
> irb(main):002:0> (!a = a)
> => true

This is actually the same as "!(a = a)".

> However neither of these two yield true in a conditional:
> puts "you wont see this" unless (a = nil) or (!a = a)

This is not correct: _because_ the second expression yields "true" you
won't see the output (you used "unless"):

irb(main):003:0> puts "you wont see this" unless (a = nil) or (!a = a)
=> nil
irb(main):004:0> puts "you wont see this" if (a = nil) or (!a = a)
you wont see this
=> nil
irb(main):005:0> (a = nil) or (!a = a)
=> true
irb(main):006:0>

Cheers

robert


PS: please try to avoid top posting.

Robert Dober

10/3/2008 9:17:00 AM

0

On Thu, Oct 2, 2008 at 9:20 PM, Trans <transfire@gmail.com> wrote:
> I wouldn't recommend that. Rule of thumb, don't use rescue when a
> regular condition does the job.

You surprise me here Tom, what is rescue for then, I mean the one line
version of course. However let us assume that you are right, what
really troubles me is the is_a? String or String#=3D=3D=3D part of the
condition.
Assuming that you should not use rescue this should be written as follows

@attributes["comments] =3D @attributes["comments"].split if
@attributes["comments"].respond_to?(:split)

Do not optimize the three lookups into assignement into a local
variable unless you have performance problems.

However I agree that the assignment to a local variable in an
ifcondition is by all means idiomatic and useful Ruby.

As is the rescue clause, I really would know more about why not to use it.


Robert



--=20
C'est v=E9ritablement utile puisque c'est joli.

Antoine de Saint Exup=E9ry

David A. Black

10/3/2008 9:49:00 AM

0

Hi --

On Fri, 3 Oct 2008, worthee@gmail.com wrote:

> Hi
>
> I was just reading the following blog post
> http://www.elctech.com/blog/clarity-over-cleverness-but-what...,
> and like the author, it is the first time I have seen code as he
> describes. From the comments it would seem that some think it is an
> idiom to be used, and perhaps others do not.
>
> Just curious as to how common this use it? I do tend to side with
> view that it is not clear at first glance.

It depends whose first glance, I guess. It was clear to me, and I
think it's something that's common enough that every Rubyist should be
ready and willing to understand it. For better or worse, clarity and
cleverness are fuzzy concepts, but in this case it's a pretty common
idiom and not a wildly inventive or convoluted elaboration of the
language. We all go through the process of not quite getting
something, and then having the "Ah ha!" moment. I don't think the fact
that the blogger you quote had that experience means that this is
something to avoid.

It's not my favorite idiom, though; it always has a slightly
unbalanced, side-effect-esque feel to it. But it's liveable with.

Ruby does something rather cool, though, to help you with this idiom:
if you do accidentally leave off the second = in a case where the rhs
can be statically determined to be true, you get a warning:

>> if x = 10; end
(irb):3: warning: found = in conditional, should be ==

There's no reason you would ever say "if x = 10", since it will be
true 100% of the time. If the rhs is not unchangeably true, you don't
get the warning:

>> y = 10
=> 10
>> if x = y; end
=> nil


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.r... for details and updates!