Local vars clobbered by un-run code

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.

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 <transfire@gmail.com> 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 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

···

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

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

Thanks matz,
T.

···

On Jun 18, 10:35 pm, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:

Hi,

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

                                                        matz.

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

···

On 6/19/07, Ian Whitlock <iw1junk@comcast.net> wrote:

Trans wrote:

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

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.

···

On Jun 19, 4:02 pm, Ian Whitlock <iw1j...@comcast.net> wrote:

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.

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

···

On 6/19/07, Trans <transfire@gmail.com> wrote:

On Jun 18, 10:35 pm, Yukihiro Matsumoto <m...@ruby-lang.org> 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 :wink:

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

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.

···

On Jun 19, 4:27 pm, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/19/07, Ian Whitlock <iw1j...@comcast.net> 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.

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.

···

On 19 jun, 07:48, "Robert Dober" <robert.do...@gmail.com> wrote:

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.

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

···

On 6/19/07, tsela.cg@gmail.com <tsela.cg@gmail.com> 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.

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

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.

···

On Jun 19, 4:30 am, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/19/07, tsela...@gmail.com <tsela...@gmail.com> 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!

"Robert Dober" <robert.dober@gmail.com> 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.

···

--
s=%q( Daniel Martin -- martin@snowplow.org
       puts "s=%q(#{s})",s.to_a.last )
       puts "s=%q(#{s})",s.to_a.last

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

:wink:

···

On 2007-06-20 07:37:14 +0900 (Wed, Jun), Daniel Martin 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.

--
No virus found in this outgoing message.
Checked by 'grep -i virus $MESSAGE'
Trust me.