Ross Bamford wrote:
> On Sun, 2006-05-28 at 18:25 +0900, transfire / gmail.com wrote:
>> Can this be done already?
>>
>>   def foo(bar, baz, bur)
>>      argsto :i, :str, :sym
>>      # something
>>    end
>>
> 
> Here's a naive implementation:
> 
> require 'facet/binding'
> 
> def argsto(*syms)
>   Binding.of_caller do |b|
>     lvs = b.local_variables
>     lvs.each do |lv|
>       break if syms.empty?
>       type = syms.shift.to_s
>       begin
>         if type =~ /^[A-Z]/
>           b[lv] = send(type, b[lv])
>         else
>           type = "to_#{type}"
>           b[lv] = b[lv].send(type)
>         end
>       rescue NameError
>         raise ArgumentError,"No coercion #{type} for #{b[lv].inspect}",
>           caller[3..-1]
>       rescue ArgumentError
>         raise ArgumentError, $!.message, caller[3..-1]
>       end
>     end
>   end
> end
> 
> If you really need this kind of thing, it seems to work:
> 
> def ameth(foo, bar, baz, &blk)
>   argsto(:Integer, :String, :sym)
>   blk.call(foo, bar, baz)
> end
> 
> ameth('10',100,'puts') { |*args| p args }
> # => [10, "100", :puts]
> 
> The added bonus you don't get if you just use to_i and and so on:
> 
> ameth('10a',100,'puts') { |*args| p args }
> -:28:in `ameth': invalid value for Integer: "10a" (ArgumentError)
>         from -:32
> 
> It's not particularly smart or fast, though. 

That's very interesting. Would it be better if class objects were given 
instead of class names? Otherwise it could be tedious to convert to 
A::B::BadgerMilk :)


Daniel