[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: adding local variables via block

Tim Pease

2/20/2007 6:52:00 PM

On 2/20/07, Paul Danese <pdanese@rib-x.com> wrote:
> Hi,
>
>
>
> i'm a roob noob and I'm trying to grasp procs/blocks/etc.
>
>
>
> specifically, I'd like to pass a piece of code into a method.
>
> the piece of code will contain a variable name and an assignment
>
>
>
> e.g.
>
>
>
> ####################
>
> def lamb_test
>
> cond = 'hello'
>
> yield
>
> puts cond + ' ' + name
>
> end
>
> lamb_test {name = 'bob'}
>
> ###################
>
>
>
> When I do this, I get the following error:
>
> "undefined local variable or method `name' for main:Object...
>
>
>
> is it possible to define a local variable like this on the fly with
> blocks?
>
> obviously, this is an oversimplified case but I want to be able to
> dynamically insert a local variable and an assignment to that variable
> into the "generic" function lamb_test
>
> Is there a better way?
>
>

yield will return the value from the block it executes. Just have your
block return the name 'bob' ...

def lamb_test
cond = 'hello'
name = yield
puts cond + ' ' + name
end

lamb_test { 'bob' } #=> 'hello bob'

In the more general case, you would need to use one of the 'eval'
methods in order to create a new local variable in a local namespace.
However, (1) the 'eval' methods work only on strings and not blocks,
and (2) they are mostly evil and should be handled with great care.

Blessings,
TwP

6 Answers

James Gray

2/20/2007 7:13:00 PM

0

On Feb 20, 2007, at 12:52 PM, Tim Pease wrote:

> In the more general case, you would need to use one of the 'eval'
> methods in order to create a new local variable in a local namespace.
> However, (1) the 'eval' methods work only on strings and not blocks,
> and (2) they are mostly evil and should be handled with great care.

eval() introduces a new scope, so local variables created in that
context do not leak into the calling scope:

>> def test_eval
>> eval("name = 'James'", binding)
>> name
>> end
=> nil
>> tes
test test_eval
>> test_eval
NameError: undefined local variable or method `name' for main:Object
from (irb):3:in `test_eval'
from (irb):5
from :0

James Edward Gray II

Patrick Hurley

2/20/2007 8:03:00 PM

0

On 2/20/07, James Edward Gray II <james@grayproductions.net> wrote:
> eval() introduces a new scope, so local variables created in that
> context do not leak into the calling scope:

I am not recommending this, but you can force a binding into an eval.
However, due to how the Ruby parser identifies local variables, they
need to be referenced in "code" before you can use them normally.

def foo(binding)
eval("x = 42", binding)
end

foo(binding)
x = x
puts "x = #{x}"

Good luck
pth

dblack

2/20/2007 8:11:00 PM

0

Marcello Barnaba

2/20/2007 8:11:00 PM

0

Hi,

On Tuesday 20 February 2007 21:02, Patrick Hurley wrote:
> I am not recommending this, but you can force a binding into an eval.
> However, due to how the Ruby parser identifies local variables, they
> need to be referenced in "code" before you can use them normally.

my irb disagrees:

vjt@neutrino:~$ irb
/home/vjt| irb(main):001:0> eval 'x = 42', binding
42
/home/vjt| irb(main):002:0> x
42
/home/vjt| irb(main):003:0> RUBY_VERSION
"1.8.5"
/home/vjt| irb(main):004:0>

--
pub 1024D/8D2787EF 723C 7CA3 3C19 2ACE 6E20 9CC1 9956 EB3C 8D27 87EF

Ara.T.Howard

2/20/2007 8:15:00 PM

0

Marcello Barnaba

2/20/2007 8:27:00 PM

0

Hi,

On Tuesday 20 February 2007 21:14, ara.t.howard@noaa.gov wrote:
> On Wed, 21 Feb 2007, Marcello Barnaba wrote:
> > Hi,
> >
> > On Tuesday 20 February 2007 21:02, Patrick Hurley wrote:
> >> I am not recommending this, but you can force a binding into an eval.
> >> However, due to how the Ruby parser identifies local variables, they
> >> need to be referenced in "code" before you can use them normally.
> >
> > my irb disagrees:
> >
> > vjt@neutrino:~$ irb
> > /home/vjt| irb(main):001:0> eval 'x = 42', binding
> > 42
> > /home/vjt| irb(main):002:0> x
> > 42
> > /home/vjt| irb(main):003:0> RUBY_VERSION
> > "1.8.5"
> > /home/vjt| irb(main):004:0>
>
> try writing that in a script.

vjt@neutrino:~$ ruby -e "eval('x=42',binding); x"
-e:1: undefined local variable or method `x' for main:Object (NameError)

> in irb you are __already__ in eval. google the archives for more info.

gotcha! :) thanks
--
pub 1024D/8D2787EF 723C 7CA3 3C19 2ACE 6E20 9CC1 9956 EB3C 8D27 87EF