[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Extract hash into local variables?

csn

2/4/2006 10:54:00 AM

Is there a Ruby function similar to PHP's extract/list? What I'd like to
do is:

def foo(args={a=>1, b=>2, c=>3})
args.extract

puts a
puts b
puts c
end

Thanks
csn

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


16 Answers

Bruno Celeste

2/4/2006 11:53:00 AM

0

Maybe args.inspect

2006/2/4, csn <cool_screen_name90001@yahoo.com>:
> Is there a Ruby function similar to PHP's extract/list? What I'd like to
> do is:
>
> def foo(args={a=>1, b=>2, c=>3})
> args.extract
>
> puts a
> puts b
> puts c
> end
>
> Thanks
> csn
>
> --
> Posted via http://www.ruby-....
>
>


Robert Klemme

2/4/2006 12:39:00 PM

0

csn <cool_screen_name90001@yahoo.com> wrote:
> Is there a Ruby function similar to PHP's extract/list? What I'd like
> to do is:
>
> def foo(args={a=>1, b=>2, c=>3})
> args.extract
>
> puts a
> puts b
> puts c
> end
>
> Thanks
> csn

You cannot do that as local variables have to be declared in the code.
You'll have to do that by hand, i.e.,

def foo(args={:a=>1, :b=>2, :c=>3})
a = args[:a] || 1
b = args[:b] || 2
a = args[:c] || 3

puts a,b,c
end

or

def foo(args={})
args = args.merge(:a=>1, :b=>2, :c=>3)
a = args[:a]
b = args[:b]
a = args[:c]

puts a,b,c
end

What do you need that for? Maybe there is a better solution.

Kind regards

robert

Gene Tani

2/4/2006 2:17:00 PM

0


Robert Klemme wrote:
> csn <cool_screen_name90001@yahoo.com> wrote:
> > Is there a Ruby function similar to PHP's extract/list? What I'd like
> > to do is:
> >
> > def foo(args={a=>1, b=>2, c=>3})
> > args.extract
> >
> > puts a
> > puts b
> > puts c
> > end
> >
> > Thanks
> > csn
>
> You cannot do that as local variables have to be declared in the code.
> You'll have to do that by hand, i.e.,
>

Robert's correct in the general case, but you can read a hash and have
locals that can be accessed through eval:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

But probably, like he said, you want to refactor

Scott

2/4/2006 6:35:00 PM

0

This is a weak solution, but:

args.each_pair { |k, v| instance_variable_set("@#{k}", v) }

will create instance variables for each key in the hash and set them to
the associated value. There may be a way to extend Hash with an
extract method, but I'm not thinking right now so :) Calling
instance_variable_set will create the variable within the scope of the
Hash, so it wont be usable where you actually want it.

Another solution could be to use OpenStruct:

def foo(args={:a=>1, :b=>2, :c=>3})
args = OpenStruct.new(args)

puts args.a
puts args.b
puts args.c
end

Hope that helps a little,
Scott

Scott

2/4/2006 6:38:00 PM

0

Duh... yea, should have read the previously posted link,
local_variable_set does make quite a bit more sense!

Jeff Schwab

2/4/2006 6:40:00 PM

0

csn wrote:
> Is there a Ruby function similar to PHP's extract/list? What I'd like to
> do is:
>
> def foo(args={a=>1, b=>2, c=>3})
> args.extract
>
> puts a
> puts b
> puts c
> end

I'm kind of disturbed by how hard this actually seems. There does not
seem to be any decent way to modify the set of local variables through
introspection. Here's a weak work-around:


def foo(args={:a=>1, :b=>2, :c=>3})
@args = args

def method_missing(m)
@args[m]
end

puts a
puts b
puts c

end

foo

Robert Klemme

2/4/2006 6:49:00 PM

0

Jeffrey Schwab <jeff@schwabcenter.com> wrote:
> csn wrote:
>> Is there a Ruby function similar to PHP's extract/list? What I'd
>> like to do is:
>>
>> def foo(args={a=>1, b=>2, c=>3})
>> args.extract
>>
>> puts a
>> puts b
>> puts c
>> end
>
> I'm kind of disturbed by how hard this actually seems. There does not
> seem to be any decent way to modify the set of local variables through
> introspection. Here's a weak work-around:
>
>
> def foo(args={:a=>1, :b=>2, :c=>3})
> @args = args
>
> def method_missing(m)
> @args[m]
> end
>
> puts a
> puts b
> puts c
>
> end

Very weak. This is by no means thread safe. Also it will keep references to
the arguments around after the method terminates. Plus, you're redefining
method_missing all the time. Too many drawbacks IMHO.

I don't know why people strive to get local variables set dynamically. If
you want to use them, you'll have to make them explicitely anyway. So what
do we gain? Is there a real world problem that can't be solved without
this?

Cheers

robert

csn

2/4/2006 7:10:00 PM

0

Thanks for the replies. I also found this bit of code:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-...

Which is similar to Scott's 'instance_variable_set' above:

def extract(hash)
hash.each do |key,value|
eval "$#{key} = #{value.inspect}"
end
end

Maybe it's possible to rewrite this into something inside of a function
which only sets local variables:

def foo(args=>{:a=>1, :b=>2, :c=>3})
for key, value in args # or for args[0..args.length] ?
eval "#{key} = #{value.inspect}"
end

puts a, b, c
end

I'm surprised there's not an easy and simple way too ;(. I read in
Programming Ruby that named arguments are planned for Ruby 2.0.

csn

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


Jeff Schwab

2/4/2006 7:22:00 PM

0

Robert Klemme wrote:
> I don't know why people strive to get local variables set dynamically.
> If you want to use them, you'll have to make them explicitely anyway.
> So what do we gain? Is there a real world problem that can't be solved
> without this?

Of course not. But some code is a lot cleaner if you can use the local
symbol table as a hash. This is a common technique in Perl, and it
seems to be in Python (via [gs]etattr and globals()) as well.

csn

2/4/2006 7:46:00 PM

0

I came up with this:

def foo(args = {'a'=>1, 'b'=>2, 'c'=>3})
a,b,c = args.values_at('a', 'b', 'c')

puts a,b,c

a,b,c = args.values

puts a,b,c
end

def foo2(args = {:a=>1, :b=>2, :c=>3})
a,b,c = args.values

puts a,b,c
end

foo outputs:
1
2
3
1
2
3

foo2 outputs:
2
3
1


csn

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