Forum: Ruby value of an expression?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-09 23:29
Sorry if this is asked before and I could not find its answer. Take a
look at the following:
------------------------------------------
1 #!/usr/bin/ruby
2 s="test"
3 puts s
4 s="surprising" if (1+1 != 2)
5 puts s
------------------------------------------
which produces the output:
test
test

but I expected it to output:
test
nil

since I thought the expression in line number 5 ("surprising" if (1+1 !=
2)) should evaluate to nil and hence s should be assigned nil.

So, my question is:
- Why?
- What should I read to understand this better?

Thank you!
-Kedar
Daec6f7c331960b73022735818b0b0d4?d=identicon&s=25 Adam Kittelson (Guest)
on 2009-01-09 23:44
(Received via mailing list)
s = "surprising" if (1+1 != 2)

There are two expressions here, and the if is acting as a modifier. The
first expression (s = "surprising") is only evaluated if the second
expression (1 + 1 != 2) evaluates as true.

It is the equivalent of:

if (1 + 1 != 2)
     s = "surprising"
end

So s = "surprising" is never evaluated, and s continues to equal "test".

Googling "ruby if modifier" should turn up some results.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-09 23:58
> It is the equivalent of:
>
> if (1 + 1 != 2)
>      s = "surprising"
> end
>
> So s = "surprising" is never evaluated, and s continues to equal "test".

Ah ok, thanks. However, I was thinking if it should be nil, not
"surprising", because of the following experience with irb:

>> "surprising" if (1+1 !=2)
=> nil

which gives an impression that the value of this entire expression is
nil.

-Kedar
F065301eb65a5d0da8edcb8de9d5e28e?d=identicon&s=25 Tim Greer (Guest)
on 2009-01-10 00:25
(Received via mailing list)
Kedar Mhaswade wrote:

> test
> - Why?
> - What should I read to understand this better?
>
> Thank you!
> -Kedar

This doesn't change because the string s is "test".  Since 1+1 is 2, it
will not change the value of s (thus it's still "test").  Only if it
were true would it result in "surprising".  It's doing exactly what it
should do.  The result of the conditional would be nil, but this is why
it's not changing it, and s remains the same value.
F065301eb65a5d0da8edcb8de9d5e28e?d=identicon&s=25 Tim Greer (Guest)
on 2009-01-10 00:30
(Received via mailing list)
Kedar Mhaswade wrote:

> Ah ok, thanks. However, I was thinking if it should be nil, not
> "surprising", because of the following experience with irb:
>
>>> "surprising" if (1+1 !=2)
> => nil
>
> which gives an impression that the value of this entire expression is
> nil.
>
> -Kedar
>

That's because the conditional isn't true.  If the conditional wasn't
nil, it would have a result (no result is nil):

irb(main):008:0> s = "surprising" if (1+1 != 2)
=> nil
irb(main):009:0> s = "surprising" if (1+1 == 2)
=> "surprising"
irb(main):010:0>

See, for example:

irb(main):010:0> s = 'value'
=> "value"

See that "puts s" has no result, you see => nil.
irb(main):011:0> puts s
value
=> nil

It does what it is supposed to do:
irb(main):010:0> s = 'value'
=> "value"
irb(main):011:0> puts s
value
=> nil
irb(main):013:0> s = "surprising" if (1+1 != 2)
=> nil <- conditional false, nil.
irb(main):014:0> puts s
value
=> nil
irb(main):015:0> s = "surprising" if (1+1 == 2)
=> "surprising"  <- conditional true, not nil.
irb(main):016:0> puts s
surprising
=> nil

These results don't change what 's' is assigned, unless it's true and s
is assigned a different value.

I hope that makes sense.
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2009-01-10 00:32
(Received via mailing list)
On Jan 9, 2009, at 5:57 PM, Kedar Mhaswade wrote:
> "surprising", because of the following experience with irb:
>
>>> "surprising" if (1+1 !=2)
> => nil
>
> which gives an impression that the value of this entire expression is
> nil.
>
> -Kedar

irb is showing the #inspect of the last expression that it evaluates.
It evaluates (1+1!=2) finds that to be false and 'if false' means that
"nothing" is returned by the expression on the left ("surprising").
That nothing is just nil.

You could convince yourself of this by running:

irb> if 1+1 != 2
irb>   "surprising"
irb>   end
=> nil

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-01-10 00:51
(Received via mailing list)
Kedar Mhaswade <kedar.mhaswade@gmail.com> writes:

> test
> test
>
> but I expected it to output:
> test
> nil
>
> since I thought the expression in line number 5 ("surprising" if (1+1 !=
> 2)) should evaluate to nil and hence s should be assigned nil.

It does.  It should not, because that's not what you wrote.

> So, my question is:
> - Why?

Because.


> - What should I read to understand this better?

The grammar of Ruby.  It's quite insipid.  Why would you lose your time
on this, don't you have anything more interesting to do?


Just write:

(s = ("surprizing" if ((1 + 1) != 2)))

or

((s = "surprizing") if ((1 + 1) != 2)))

depending on what you mean.
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-01-10 00:51
(Received via mailing list)
Adam Kittelson <adam.kittelson@apathydrive.com> writes:

> if (1 + 1 != 2)
>      s = "surprising"
> end

Why is it not equivalent to:

    s = if (1 + 1 != 2)
          s = "suprising"
        end

?



(rethorical question).
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-10 00:52
> I hope that makes sense.

Ah, it does. Thanks. I was confusing it what irb "echoes".
F065301eb65a5d0da8edcb8de9d5e28e?d=identicon&s=25 Tim Greer (Guest)
on 2009-01-10 00:56
(Received via mailing list)
Pascal J. Bourguignon wrote:


> Just write:
>
> (s = ("surprizing" if ((1 + 1) != 2)))

irb would have shown the result as nil for that specific test and they'd
have asked the same question, I think.  However, I won't guess what
they intended to do or how. :-)

> or
>
> ((s = "surprizing") if ((1 + 1) != 2)))
                                      ^^^

oops... you meant: ((s = "surprizing") if ((1 + 1) != 2))
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-01-10 01:00
(Received via mailing list)
Tim Greer <tim@burlyhost.com> writes:

>
>> or
>>
>> ((s = "surprizing") if ((1 + 1) != 2)))
>                                       ^^^
>
> oops... you meant: ((s = "surprizing") if ((1 + 1) != 2))

Right, I corrected it in the irb buffer and forgot to backpatch the gnus
buffer.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-10 01:06
Sorry, I had a glimmer of hope but this script eclipsed it :(
confused.rb
-----------
#!/usr/bin/ruby

s="test"
puts s
s="surprising" if (1+1!=2)
puts s
s=("surprising" if (1+1!=2))
puts s
------------

Outputs:
test
test
nil

so, to add to a newbie's confusion, a pair of parenthesis does the
expected.



-Kedar
F065301eb65a5d0da8edcb8de9d5e28e?d=identicon&s=25 Tim Greer (Guest)
on 2009-01-10 01:25
(Received via mailing list)
Kedar Mhaswade wrote:

> s=("surprising" if (1+1!=2))

That is because when it's all in paranthsis, it is assigning the value
of the conditional.  That can be useful when used properly.
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-01-10 01:55
(Received via mailing list)
Kedar Mhaswade <kedar.mhaswade@gmail.com> writes:
> puts s
> ------------
>
> Outputs:
> test
> test
> nil
>
> so, to add to a newbie's confusion, a pair of parenthesis does the
> expected.

What did you expect?

case 1:
(s = "surprising") if ((1 + 1) != 2)  won't assign unless (1+1)!=2

case 2:
s = ("surprising" if ((1 + 1) != 2))  will assign the result of the
parenthese, which will be "surprising" if ((1 + 1) != 2) (and nil
otherwise).
If you wanted not to do any assignment to s, then you should go back to
case 1.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-10 04:43
Pascal J. Bourguignon wrote:
> Kedar Mhaswade <kedar.mhaswade@gmail.com> writes:
>> puts s
>> ------------
>>
>> Outputs:
>> test
>> test
>> nil
>>
>> so, to add to a newbie's confusion, a pair of parenthesis does the
>> expected.
>
> What did you expect?
>
> case 1:
> (s = "surprising") if ((1 + 1) != 2)  won't assign unless (1+1)!=2
>
> case 2:
> s = ("surprising" if ((1 + 1) != 2))  will assign the result of the
> parenthese, which will be "surprising" if ((1 + 1) != 2) (and nil
> otherwise).
> If you wanted not to do any assignment to s, then you should go back to
> case 1.

Tim and Pascal,

I certainly appreciate your attempts to make me get it. I think I am
close. The only weird thing is I was not sure whether
"surprising" if (1+1 != 2)
is an "expression" and if yes, what its value was. I thought that this
expression is same as ("surprising" if (1+1 != 2)) and both should
evaluate to the same value.

Thus, whereas now I get that the value of ("surprising" if (1+1 != 2))
is nil, it is not clear to me if
- "surprising" if (1+1 != 2) is an expression and evaluates to some/same
value.

Apologies if this is becoming rather lengthy.

Regards,
Kedar
7a561ec0875fcbbe3066ea8fe288ec77?d=identicon&s=25 Sebastian Hungerecker (Guest)
on 2009-01-10 04:52
(Received via mailing list)
Pascal J. Bourguignon wrote:
> Why is it not equivalent to:
>
>     s = if (1 + 1 != 2)
>           s = "suprising"
>         end
>
> ?

Because of precedence. If you'd write s = ("surprising" if (1+1!=2)), it
would
be equivalent to the above.

> (rethorical question).

Oops.
F065301eb65a5d0da8edcb8de9d5e28e?d=identicon&s=25 Tim Greer (Guest)
on 2009-01-10 07:10
(Received via mailing list)
Kedar Mhaswade wrote:

>>> so, to add to a newbie's confusion, a pair of parenthesis does the
>> otherwise).
> evaluate to the same value.
>
>

I think the response mode irb defaults to, is confusing you.  When you
use irb, for the sake of clarifying what you were expecting previously,
use the --noinspect option (i.e., irb --noinspect).
9e2504e0b74e5384af09ce8a660afac4?d=identicon&s=25 Pascal J. Bourguignon (Guest)
on 2009-01-10 08:55
(Received via mailing list)
Kedar Mhaswade <kedar.mhaswade@gmail.com> writes:
> value.
Is it not the same?

irb(main):698:0> "surprising" if (1+1 != 2)
nil
irb(main):699:0> ("surprising" if (1+1 != 2))
nil
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-01-10 11:00
(Received via mailing list)
On 10.01.2009 04:43, Kedar Mhaswade wrote:

> I certainly appreciate your attempts to make me get it. I think I am
> close. The only weird thing is I was not sure whether
> "surprising" if (1+1 != 2)
> is an "expression" and if yes, what its value was. I thought that this
> expression is same as ("surprising" if (1+1 != 2)) and both should
> evaluate to the same value.

They _are_ the same and they do evaluate to the same value.  However,
the point which probably hasn't become clear so far is this: the
assignment is part of the expression that's conditionally evaluated.  If
the expression isn't evaluated, no assignment happens.

x = 0
(x = 1) if false
x = 1 if false # same as above

In this case the assignment with 1 is never executed and hence the value
of the variable does not change.  The result of the _whole_ expression
however is either nil (in case of the condition evaluating to false) or
the result of evaluating the expression before the "if".

Assignments happen to be defined as expressions in Ruby (everything is -
there is no distinction between statement and expression like in some
other languages).  So they have a result like evaluating any other
expression like (1 + 3) for example.   The way it is defined the result
of an assignment expression is the right hand side.  You can view the
change of the variable as a side effect of evaluating the assignment
expression.

That's also the reason why you can do assignment chains like

a = b = c = 0

Assignments are evaluated right to left (as opposed to 1 + 2 + 3 for
example which is evaluated left to right).  The result of "c = 0" is a)
c now points to object 0 and b) 0 is also returned as result of
evaluating this, so in the end you get

(a = (b = (c = 0)))

> Thus, whereas now I get that the value of ("surprising" if (1+1 != 2))
> is nil, it is not clear to me if
> - "surprising" if (1+1 != 2) is an expression and evaluates to some/same
> value.

Yes, it is an expression and evaluates the way I have tried to outline
above.  Everything is an expression in Ruby, even a case statement which
comes in handy from time to time:

foo = case x
   when String
     "it's a String"
   when Fixnum, Integer, Float
     "it's a number"
   else
     "I have no idea"
   end

puts foo

A final remark, if your aim is to assign nil in case the condition is
false, the ternary operator is probably a better choice:

s = (1+1 != 2) ? "surprising" : nil
s = 1+1 != 2 ? "surprising" : nil
s = 1+1 == 2 ? nil : "surprising"

You can as well use if else which is more verbose

s = if (1+1 != 2) then "surprising" else nil end

The main point is to make the assignment unconditional.

> Apologies if this is becoming rather lengthy.

No worries.  That's ok.

Kind regards

  robert
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2009-01-10 21:24
>
> In this case the assignment with 1 is never executed and hence the value
> of the variable does not change.  The result of the _whole_ expression
> however is either nil (in case of the condition evaluating to false) or
> the result of evaluating the expression before the "if".
>
> Assignments happen to be defined as expressions in Ruby (everything is -
> there is no distinction between statement and expression like in some
> other languages).  So they have a result like evaluating any other
> expression like (1 + 3) for example.   The way it is defined the result
> of an assignment expression is the right hand side.  You can view the
> change of the variable as a side effect of evaluating the assignment
> expression.
>

Thanks Robert. I get it now.

Regards,
Kedar
This topic is locked and can not be replied to.