Shadowing bug?

Hi,

def f_ok(node)
  func = lambda {|n| p(:in_lambda, n); n }
  p node, func.call(node[:xpto]), node
end

f_ok({:xpto => "ohoh"})

:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
{:xpto=>"ohoh"}

def f_ko(node)
  func = lambda {|node| p(:in_lambda, node); node }
  p node, func.call(node[:xpto]), node
end

f_ko({:xpto => "ohoh"})

:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
"ohoh" # ohoh... should be {:xpto=>"ohoh"}, or not??

I can't get any kind of explanation for this. Does anybody have one?
Why "node" in lambda isn't shadowed correctly (as i expected, at least)?
Well "node" is shadowed correctly but seems to be producing side
effects...

Thanks,
Vasco Andrade e Silva

···

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

Vasco Andrade e Silva wrote:

Hi,

def f_ok(node)
  func = lambda {|n| p(:in_lambda, n); n }
  p node, func.call(node[:xpto]), node
end

f_ok({:xpto => "ohoh"})

:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
{:xpto=>"ohoh"}

def f_ko(node)
  func = lambda {|node| p(:in_lambda, node); node }
  p node, func.call(node[:xpto]), node
end

f_ko({:xpto => "ohoh"})

:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
"ohoh" # ohoh... should be {:xpto=>"ohoh"}, or not??

I can't get any kind of explanation for this. Does anybody have one?
Why "node" in lambda isn't shadowed correctly (as i expected, at least)?
Well "node" is shadowed correctly but seems to be producing side
effects...

Thanks,
Vasco Andrade e Silva

I remember someone mentioned that it's possible to do some strange things in lambda (modyfing variable passed beeing one of them), but there's nothing in this funcition or lambda that would modify "node", i think there might be a scope problem that makes node variable in function beeing overvriten when part of node is in lambda

irb(main):014:0> def f_ko(node)
irb(main):015:1> func = lambda {|node| p(:in_lambda, node); node }
irb(main):016:1> p node, func.call("bleh"), node
irb(main):017:1> end
=> nil
irb(main):018:0> f_ko({:xpto => "ohoh"})
:in_lambda
"bleh"
{:xpto=>"ohoh"}
"bleh"
=> nil

this seems to confirm that using |node| will overwrite node in function, i'm not sure if it's intended scope behaviour tho

This is a somewhat similar situation where a variable isn't all that
local:

x = 1
(2..3).each {|x|}
p x
=> 3

I think this is intended though and AFAIK this behaviour is subject
to
change in 2.0 and maybe has already changed in 1.9.

tho_mica_l wrote:

This is a somewhat similar situation where a variable isn't all that
local:

x = 1
(2..3).each {|x|}
p x
=> 3

Exactly!

I think this is intended though and AFAIK this behaviour is subject
to
change in 2.0 and maybe has already changed in 1.9.

I tested in ruby1.9 and the "bug" seems fixed:

RUBY_VERSION

"1.9.0"

x = 1
(2..3).each {|x|}
p x

1

f_ko({:xpto => "ohoh"})

:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
{:xpto=>"ohoh"} # :slight_smile:

Thank you people,
Vasco Andrade e Silva

···

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

# x = 1
# (2..3).each {|x|}
# p x
# => 3

···

From: tho_mica_l [mailto:micathom@gmail.com]
#
# I think this is intended though and AFAIK this behaviour is subject
# to change in 2.0 and maybe has already changed in 1.9.

indeed.
C:\ruby1.9\bin>irb

irb(main):001:0> x = 1
=> 1
irb(main):002:0> (2..3).each {|x|}
=> 2..3
irb(main):003:0> p x
1
=> 1

kind regards -botp

Just let me add that even though this is fixed IMHO it is a bad idea
to use the same identifier in both cases if you want to keep them
separate. This can likely cause confusion.

Kind regards

robert

···

2007/11/14, Vasco Andrade e Silva <vascoas@gmail.com>:

tho_mica_l wrote:
> This is a somewhat similar situation where a variable isn't all that
> local:
>
> x = 1
> (2..3).each {|x|}
> p x
> => 3
Exactly!

>
> I think this is intended though and AFAIK this behaviour is subject
> to
> change in 2.0 and maybe has already changed in 1.9.

I tested in ruby1.9 and the "bug" seems fixed:
> RUBY_VERSION
"1.9.0"
> x = 1
> (2..3).each {|x|}
> p x
1

> f_ko({:xpto => "ohoh"})
:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
{:xpto=>"ohoh"} # :slight_smile:

--
use.inject do |as, often| as.you_can - without end

Robert Klemme wrote:

>
1

> f_ko({:xpto => "ohoh"})
:in_lambda
"ohoh"
{:xpto=>"ohoh"}
"ohoh"
{:xpto=>"ohoh"} # :slight_smile:

Just let me add that even though this is fixed IMHO it is a bad idea
to use the same identifier in both cases if you want to keep them
separate. This can likely cause confusion.

I don't agreed with you. Shadowing, IMHO, is a very useful (and
powerful) way to express semantic and execute "best practices".

Example:
Imagine you want to process a tree (as i wanted). Suppose that in the
process of that computation you call "defn_to_sexp". This method
receives a node (tagged with :defn).
In this case i wanted to do a "special" process to the args branch of
the tree. So, and because i didn't want to declare another function
visible from class scope, i created a proc (process_args). This proc
should receive the tree branch (i.e. "node") and other variable witch
represents a computation over some other branch of defn's node.

Here goes a simple sample:
def defn_to_sexp(node)
  process_args = lambda do |n, has_block|
    ...
  end
  ...
  has_block = process(...)
  process_args.call(args_node(node), hash_block)
  ...
end

i have more semantic if i can call the word "node" instead of the word
"n" in lambda's arg: I want to shadow the node variable.
This is a case, IMHO, where it's a good idea "to use the same identifier
in both cases".

In this case i would wanted to write:
def defn_to_sexp(node)
  process_args = lambda do |node, has_block|
    ... # i don't want to access to the outer node
        # and "node" says more than "n"
  end
  ...
  has_block = process(...)
  process_args.call(args_node(node), hash_block)
  ...
end

Regards,
Vasco Andrade e Silva

···

2007/11/14, Vasco Andrade e Silva <vascoas@gmail.com>:

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

IMHO you are abusing a lambda to get a nested method. This likely
also has performance impacts since the block has to be recreated on
every invocation of the method. In this case I'd rather use a private
helper method.

But I can see how you would want to use the same identifier in some
cases. I can only speak for myself: I did not feel the urge to do
this (yet).

Cheers

robert

···

2007/11/15, Vasco Andrade e Silva <vascoas@gmail.com>:

Robert Klemme wrote:
> 2007/11/14, Vasco Andrade e Silva <vascoas@gmail.com>:
>> >
>> 1
>>
>> > f_ko({:xpto => "ohoh"})
>> :in_lambda
>> "ohoh"
>> {:xpto=>"ohoh"}
>> "ohoh"
>> {:xpto=>"ohoh"} # :slight_smile:
>
> Just let me add that even though this is fixed IMHO it is a bad idea
> to use the same identifier in both cases if you want to keep them
> separate. This can likely cause confusion.

I don't agreed with you. Shadowing, IMHO, is a very useful (and
powerful) way to express semantic and execute "best practices".

Example:
Imagine you want to process a tree (as i wanted). Suppose that in the
process of that computation you call "defn_to_sexp". This method
receives a node (tagged with :defn).
In this case i wanted to do a "special" process to the args branch of
the tree. So, and because i didn't want to declare another function
visible from class scope, i created a proc (process_args). This proc
should receive the tree branch (i.e. "node") and other variable witch
represents a computation over some other branch of defn's node.

Here goes a simple sample:
def defn_to_sexp(node)
  process_args = lambda do |n, has_block|
    ...
  end
  ...
  has_block = process(...)
  process_args.call(args_node(node), hash_block)
  ...
end

i have more semantic if i can call the word "node" instead of the word
"n" in lambda's arg: I want to shadow the node variable.
This is a case, IMHO, where it's a good idea "to use the same identifier
in both cases".

In this case i would wanted to write:
def defn_to_sexp(node)
  process_args = lambda do |node, has_block|
    ... # i don't want to access to the outer node
        # and "node" says more than "n"
  end
  ...
  has_block = process(...)
  process_args.call(args_node(node), hash_block)
  ...
end

--
use.inject do |as, often| as.you_can - without end

Robert Klemme wrote:

>> {:xpto=>"ohoh"} # :slight_smile:
process of that computation you call "defn_to_sexp". This method
    ...
in both cases".
  ...
end

IMHO you are abusing a lambda to get a nested method. This likely
also has performance impacts since the block has to be recreated on
every invocation of the method. In this case I'd rather use a private
helper method.

But I can see how you would want to use the same identifier in some
cases. I can only speak for myself: I did not feel the urge to do
this (yet).

I think that has to do a lot with your "school".
Have a try with it, i'm sure you'll love it after while :stuck_out_tongue:

Cheers

robert

Let me only add if you want performance in this case you could just do:
@process_args ||= lambda do |node, has_block|
    ... # i don't want to access to the outer node
        # and "node" says more than "n"
  end

this is a very simple cache system :wink:

Regards,
Vasco

···

2007/11/15, Vasco Andrade e Silva <vascoas@gmail.com>:

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

Robert Klemme wrote:
>> >> {:xpto=>"ohoh"} # :slight_smile:
>> process of that computation you call "defn_to_sexp". This method
>> ...
>> in both cases".
>> ...
>> end
>
> IMHO you are abusing a lambda to get a nested method. This likely
> also has performance impacts since the block has to be recreated on
> every invocation of the method. In this case I'd rather use a private
> helper method.
>
> But I can see how you would want to use the same identifier in some
> cases. I can only speak for myself: I did not feel the urge to do
> this (yet).

I think that has to do a lot with your "school".
Have a try with it, i'm sure you'll love it after while :stuck_out_tongue:

This is a melody that drastically increases the likelihood that I do
*not* do it because it is usually used by people that want my money.
:-))

From what I've seen so far I do not think I gain any advantages, so
sorry, I stick with my "old school". :slight_smile:

Let me only add if you want performance in this case you could just do:
@process_args ||= lambda do |node, has_block|
    ... # i don't want to access to the outer node
        # and "node" says more than "n"
  end

this is a very simple cache system :wink:

Yes, and it has the drawback to at least potentially hold on to
objects longer than needed... :slight_smile:

Kind regards

robert

···

2007/11/16, Vasco Andrade e Silva <vascoas@gmail.com>:

> 2007/11/15, Vasco Andrade e Silva <vascoas@gmail.com>:

--
use.inject do |as, often| as.you_can - without end

Hi (again),

In "Programing Ruby: The Pragmatic Programmers Guide (2dn Ed.)" Book,
pp. 333:
<quote>
Block parameters are assigned values when the block is invoked.
...
If a local variable (including a block parameter) is first assigned in a
block, it is local to the block. If instead a variable of the same name
is already established at the time the block executes, the block will
inherit that variable.
</quote>

As far as i can see in that text it describes (spec's)
x = 1
(2..3).each {|x|}
p x
=> 3
to a correct case..

I need to know:
1) Is this the behavior we should expect from the ruby language (1.8)?
2) Since ruby (1.9) does not behave the same way:
x = 1
(2..3).each {|x|}
p x
=> 1
what should be the spec for block parameters?

Thanks (once more),
Vasco

···

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