Forum: Ruby local vars clobbered by un-run code

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.
Trans (Guest)
on 2007-06-19 06:21
(Received via mailing list)
Err...

  irb(main):001:0> def x; 1; end
  => nil
  irb(main):002:0> p x
  1
  => nil
  irb(main):003:0> if false
  irb(main):004:1>   x = x() + 1
  irb(main):005:1> end
  => nil
  irb(main):006:0> x
  => nil

Don't tell me, it's some quirk of the way Ruby works. Sure looks like
a bug though. Just in case:

  ruby 1.8.4 (2005-12-24) [i486-linux]

Hmm... I just got a dejavu. Maybe I came across this before.

T.
Yukihiro M. (Guest)
on 2007-06-19 06:36
(Received via mailing list)
Hi,

It's not a bug.  Assignments makes identifiers local variables,
statically.

              matz.

In message "Re: local vars clobbered by un-run code"
    on Tue, 19 Jun 2007 11:21:03 +0900, Trans 
<removed_email_address@domain.invalid>
writes:
|
|Err...
|
|  irb(main):001:0> def x; 1; end
|  => nil
|  irb(main):002:0> p x
|  1
|  => nil
|  irb(main):003:0> if false
|  irb(main):004:1>   x = x() + 1
|  irb(main):005:1> end
|  => nil
|  irb(main):006:0> x
|  => nil
|
|Don't tell me, it's some quirk of the way Ruby works. Sure looks like
|a bug though. Just in case:
|
|  ruby 1.8.4 (2005-12-24) [i486-linux]
|
|Hmm... I just got a dejavu. Maybe I came across this before.
|
|T.
Trans (Guest)
on 2007-06-19 06:54
(Received via mailing list)
On Jun 18, 10:35 pm, Yukihiro M. <removed_email_address@domain.invalid> wrote:
> Hi,
>
> It's not a bug.  Assignments makes identifiers local variables,
> statically.
>
>                                                         matz.

This must be the matz-bot. The answer came instantaneously and, deja-
vu again, I think it's same one I got before ;)

Thanks matz,
T.
Robert D. (Guest)
on 2007-06-19 09:49
(Received via mailing list)
On 6/19/07, Trans <removed_email_address@domain.invalid> wrote:
> This must be the matz-bot. The answer came instantaneously and, deja-
> vu again, I think it's same one I got before ;)
Let us see?

Which assignment Matz?

irb(main):001:0> def x;1 end
=> nil
irb(main):002:0> if false then
irb(main):003:1* def x; 2 end
irb(main):004:1> end
=> nil
irb(main):005:0> x
=> 1
irb(main):006:0> def y; 1 end
=> nil
irb(main):007:0> if false
irb(main):008:1> undef y
irb(main):009:1> end
=> nil
irb(main):010:0> y
=> 1

Surely the statements inside if are not executed.

Cheers
Robert
unknown (Guest)
on 2007-06-19 12:21
(Received via mailing list)
On 19 jun, 07:48, "Robert D." <removed_email_address@domain.invalid> wrote:
> => nil
>
> Surely the statements inside if are not executed.
>

No, but they are parsed. And identifiers are made local variables at
parse time, not at execution time. So if you have an assignment
anywhere, even in a place that will never actually execute, the
identifier used in the assignment will be considered a local variable
by the interpreter.

Christophe.
Robert D. (Guest)
on 2007-06-19 12:31
(Received via mailing list)
On 6/19/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:

>
> No, but they are parsed. And identifiers are made local variables at
> parse time, not at execution time. So if you have an assignment
> anywhere, even in a place that will never actually execute, the
> identifier used in the assignment will be considered a local variable
> by the interpreter.
>
> Christophe.

I guess this can be concluded by what is happening, but is this any
reason to accept this behavior? I honestly do not feel so!

Cheers
Robert
Trans (Guest)
on 2007-06-19 17:28
(Received via mailing list)
On Jun 19, 4:30 am, "Robert D." <removed_email_address@domain.invalid> wrote:
> > Christophe.
>
> I guess this can be concluded by what is happening, but is this any
> reason to accept this behavior? I honestly do not feel so!

I do not feel so either. But, I've also learned that Ruby just has
some quirks. Matz wouldn't had done it this way unless there was a
very real need to do so. Now, that's not to say he might not have
missed a better solution, so it's still worth discussing if anyone has
one.

T.
Ian W. (Guest)
on 2007-06-20 00:02
Trans wrote:

>
> Don't tell me, it's some quirk of the way Ruby works. Sure looks like
> a bug though. Just in case:
>
>   ruby 1.8.4 (2005-12-24) [i486-linux]
>
> Hmm... I just got a dejavu. Maybe I came across this before.
>
> T.

T all you showed is that sometimes the programmer must be responsible
for knowing whether he wants to reference a function or a variable.

Consider:

def x
  1
end

p x              #recognize function call without parens

if false
  x = x() + 1    #variable x is created when code parsed
end

p x    #reference the variable x which is nil because no assignment was
made
p x()  #if the above were the function, how would you reference the
variable?

Result:

1
nil
1

Ian
Robert D. (Guest)
on 2007-06-20 00:27
(Received via mailing list)
On 6/19/07, Ian W. <removed_email_address@domain.invalid> wrote:
> Trans wrote:
Tom it just strikes me, your thread and mine about Singleton classes
not being in ancestors and small other things I always see the same
pattern. Rick's blog entry is another example, always the same
pattern, it is the pattern of imperfection which is the  *only* thing
that slightly bothers me in Ruby:


   Consistency.

Maybe, probably I am wrong, but I feel that when it comes to these
subtle things Ruby is lacking consistency.

There just seems no reason for some behavior and your example above is
a classical example. You ask yourself why and you cannot find an
answer.

And worst of all, you have to remember!!

Still a great, great language of course.

Robert
Trans (Guest)
on 2007-06-20 01:25
(Received via mailing list)
On Jun 19, 4:02 pm, Ian W. <removed_email_address@domain.invalid> wrote:
>
> T all you showed is that sometimes the programmer must be responsible
> for knowing whether he wants to reference a function or a variable.

One of things I always liked about Ruby is the fact the local vars and
methods are, in a certain sens of the word, polymorphic. Where a
method is being called, I can easily change it to be a variable. I
don't have to go thru the code and remove ()s or vice versa.

  def chip
     "%s chip"
  end

  def good
    chip = "forget the %s chip"
    puts chip % "good"
  end

So if you can do that, it would seem reasonable that one could do so
conditionally as well. I find it odd that x is being setup as a local
var before ever being assigned as such. That's quite declarative for a
language that tends to shuns such things.

T.
Trans (Guest)
on 2007-06-20 01:31
(Received via mailing list)
On Jun 19, 4:27 pm, "Robert D." <removed_email_address@domain.invalid> wrote:
> Maybe, probably I am wrong, but I feel that when it comes to these
> subtle things Ruby is lacking consistency.
>
> There just seems no reason for some behavior and your example above is
> a classical example. You ask yourself why and you cannot find an
> answer.
>
> And worst of all, you have to remember!!
>
> Still a great, great language of course.

That is true. Ruby does have some rough edges. Though I chalk much of
it up to the fact that convenience and flexibility often comes with a
price of a few quirks.

T.
Daniel M. (Guest)
on 2007-06-20 02:38
(Received via mailing list)
"Robert D." <removed_email_address@domain.invalid> writes:

> I guess this can be concluded by what is happening, but is this any
> reason to accept this behavior? I honestly do not feel so!

On the other hand, I find the idea that the scoping and binding of
variables could change based on the particular code path followed at
run time a horribly non-intuitive concept, since I think of "variable
scope" as something as static as the code itself - that is, you should
only be able to screw with variable scoping by strange
meta-programming tricks.
Mariusz Pękala (Guest)
on 2007-06-20 17:33
(Received via mailing list)
On 2007-06-20 07:37:14 +0900 (Wed, Jun), Daniel M. wrote:
> On the other hand, I find the idea that the scoping and binding of
> variables could change based on the particular code path followed at
> run time a horribly non-intuitive concept, since I think of "variable
> scope" as something as static as the code itself - that is, you should
> only be able to screw with variable scoping by strange
> meta-programming tricks.

Maybe I don't understand something, but the decision whether something
is a variable or is a method call is based not on the code executed
(which is hard to predict when reading the source) but on the code
parsed, which is pretty static.

def this_method( x )
  p y           # This 'y' will always be a method call.
                # (even if you call this_method again)
  if x
    y = 1       # because of this line in the source code...
  end
  p y           # ...this 'y' will always be a variable.
end             # ..independent on the value of x

So, I would (IMHO) assume, that this is not bad-black-magic, but
good-and-understandable-white-magic aspect of ruby.

The confision may emerge when the block of code has many lines, hard to
grasp in one eye shot, but I have been taught that if you write a
function that is longer than half of your editor window you should
extract part of it into another function.
With short blocks it is harder to mistake a method for a variable.

P.S.:
If someone still does not like this magic behaviour, assume that it
saves you from writing:

def this_method( x )
  p y
  if x
#pragma set_as_variable(y) /* and if you forgot, you will get
parse-error */
    y = 1
  end
  p y
end

;-)
This topic is locked and can not be replied to.