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-forum.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-forum.com/.
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.extractputs a
puts b
puts c
endThanks
csn--
Posted via http://www.ruby-forum.com/\.
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
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.extractputs a
puts b
puts c
endThanks
csn
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
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.extractputs 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 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
> csnYou 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-talk/159842
But probably, like he said, you want to refactor
Duh... yea, should have read the previously posted link,
local_variable_set does make quite a bit more sense!
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
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.extractputs a
puts b
puts c
endI'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 = argsdef method_missing(m)
@args[m]
endputs a
puts b
puts cend
Thanks for the replies. I also found this bit of code:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/41812
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-forum.com/.
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.
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-forum.com/.
Careful with that, I think hash order is undefined?
I was playing a bit with this stuff recently and came up with this:
class Method
def arg_names
catch(:traced) do
dummy_args = [nil]
dummy_args *= self.arity unless self.arity < 0
set_trace_func lambda { |event, file, line, id, bdng, cls|
if event == 'call'
set_trace_func nil
throw(:traced, eval('local_variables',bdng).map { |lv| lv.intern })
end
}
self.call(*dummy_args)
# if we get here, call is bust
set_trace_func nil
raise "No ruby method call in block"
end
end
def hcall(hash, &blk)
names = arg_names.reject { |n| n =~ /^(.*proc|bl(oc)?k)$/ }
call(*names.map { |n| hash[n] or raise "Missing argument" }, &blk)
end
end
def foo(a,b,c)
p [a,b,c]
end
method(:foo).hcall(:c => 'C', :a => 'A', :b => 'B')
# => ["A", "B", "C"]
but it's block argument handling is very weak and it can't handle methods implemented in C. Better to just wait for Ruby 2.0. Personally, I've never once missed them anyway.
On Sat, 04 Feb 2006 19:46:03 -0000, csn <cool_screen_name90001@yahoo.com> wrote:
def foo2(args = {:a=>1, :b=>2, :c=>3})
a,b,c = args.valuesputs a,b,c
end
--
Ross Bamford - rosco@roscopeco.remove.co.uk
Ruby != Perl && Ruby != Python
I'd rather discuss this with a real world example that demonstrates
where this idiom is really needed or at least superior in clarity. ATM
I fail to see where this would bring real benefits.
Cheers
robert
2006/2/4, Jeffrey Schwab <jeff@schwabcenter.com>:
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.
--
Have a look: Robert K. | Flickr
Jeffrey Schwab wrote:
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.
I think on this specific point you're wrong about python. Writing to
globals dict will change the global namespace, writing to locals dict
won't have any effect (it's often described as read-only, but that's
not quite correct)
Maybe we're arguing about passing keywords args to a method, in which
case you can look at Gavin Sinclair's solution in the draft Ruby
cookbook.
Jeffrey Schwab <jeff@schwabcenter.com> writes:
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.
If that's true, consider it a good reason *not to*.
Local variables are local variables and not meant to be syntactic
shortcuts for anything else.
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org
Jeffrey Schwab wrote:
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.
It may be common in Perl, but it is just as misguided there as well.
Read Why it's stupid to `use a variable as a variable name' for details.
Gene Tani wrote:
Maybe we're arguing about passing keywords args to a method, in which
case you can look at Gavin Sinclair's solution in the draft Ruby
cookbook.
it's here too