# Argument hash to string to proc to instance variables

**URL:** <https://www.ruby-forum.com/t/argument-hash-to-string-to-proc-to-instance-variables/104082>\
**Category:** Ruby\
**Created:** [May 14, 2007, 6:16am UTC](https://www.ruby-forum.com/t/argument-hash-to-string-to-proc-to-instance-variables/104082 "2007-05-14T06:16:00Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [May 14, 2007, 6:16am UTC](https://www.ruby-forum.com/t/argument-hash-to-string-to-proc-to-instance-variables/104082/1 "2007-05-14T06:16:00Z")

</div>

It is idiomatic to pass a number of related arguments (usually config  
related) as the last (braceless argument) to a method ( heavily used  
in Rails ) e.g .

def my\_method(arg1, arg2)  
end

where arg1 is anything and arg2 is a hash

my\_method(“hello”, :a=\>“nasir”, :b =\> 30, :c=“khan”) etc.

It is also quite popular to instance\_eval a block to initialize a  
number of attributes rather than pass them all upfront to “new”. e.g.

class A  
attr\_accessor :a, :b, :c  
def initialize(&block)  
instance\_eval(&block) if block\_given?  
end  
end

x = A.new do  
self.a = “hello”;  
self.b = 1;  
self.c = “bye”;  
end

It is also trivial to use these two techniques together i.e. take the  
hash argument in the method and use it to create a proc which can be  
evaled as a block e.g.

def my\_method(arg1, arg2)  
str = “lambda { "  
arg2.each\_pair {|k,v| str \<\< sprintf(“self.%s=%s;”, k, v) }  
str \<\< " }”  
p = eval str  
x = A.new &p  
end  
end

Here “my\_method” returns the instance of class A initialized with the  
attributes given  
as hash which is converted to block and instance\_evaled in the  
initialize method of class A.

All this works but I am doing _two_ evals (one for string to proc in  
my\_method and one the instance\_evaling of block in initialize, not to  
mention constructing the string for proc.

Is there is a simpler/faster alternative that I have overlooked?

- Nasir

---

<div class="post-metadata">

**Author:** ![Nasir\_K](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/838e76/32.png) [@Nasir\_K](https://www.ruby-forum.com/u/Nasir_K)\
**Post date:** [May 14, 2007, 7:41am UTC](https://www.ruby-forum.com/t/argument-hash-to-string-to-proc-to-instance-variables/104082/2 "2007-05-14T07:41:05Z")

</div>

On Mon, May 14, 2007 at 01:14:54PM +0900, Nasir K. wrote:

> x = A.new do  
> str = "lambda { "  
> initialize method of class A.
> 
> All this works but I am doing _two_ evals (one for string to proc in  
> my\_method and one the instance\_evaling of block in initialize, not to  
> mention constructing the string for proc.
> 
> Is there is a simpler/faster alternative that I have overlooked?

Don’t worry about instance\_eval with a block. All it does it change  
‘self’  
and run the existing block; you are not running the compiler.

It’s the string form of eval which should concern you, as (a) you’re  
compiling code on the fly, which is inefficient, and (b) you have to be  
very  
careful about injection attacks, e.g.

my\_method(nil, :foo =\> ‘system(“rm -rf /\*”)’)

You could use ‘send’ or ‘instance\_variable\_set’ instead. i.e.

send("#{k}=", v) # invoke the #{k}= method  
or  
instance\_variable\_set("@#{k}", v) # set @{k} to v

You’ll see the first form in ActiveRecord quite a lot.

Regards,

Brian.
