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…
{:xpto=>“ohoh”}
“ohoh”
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
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.
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
{:xpto=>“ohoh”} #
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).
{:xpto=>“ohoh”} #
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
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
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
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”.
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
Yes, and it has the drawback to at least potentially hold on to
objects longer than needed…
In “Programing Ruby: The Pragmatic Programmers Guide (2dn Ed.)” Book,
pp. 333:
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.
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:
Is this the behavior we should expect from the ruby language (1.8)?
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.