# My\_define\_method

**URL:** <https://www.ruby-forum.com/t/my-define-method/211011>\
**Category:** IT\
**Created:** [August 23, 2011, 3:43pm UTC](https://www.ruby-forum.com/t/my-define-method/211011 "2011-08-23T15:43:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [August 23, 2011, 3:43pm UTC](https://www.ruby-forum.com/t/my-define-method/211011/1 "2011-08-23T15:43:32Z")

</div>

Salve ragazzi, studiando meta-programming in Ruby mi sono riproposto di  
scrivere un metodo, my\_define\_method(), che emuli Module#define\_method o  
che grosso modo, si comporti in maniera simile. ho pensato al seguente  
snippet:

class Module

def my\_define\_method method\_name, &block  
self.class\_eval(“def #{method\_name} \*args; #{ block.call() }; end;  
end;”)  
end

end

Il mio problema è : come faccio dentro #{block.call( … ) a riferirmi  
ad  
\*args ?

Client code:

AClass.my\_define\_method “metodo” do |x,y,z|  
puts “Numeri : #{x},#{y},#{z}”  
end

obj = AClass.new  
obj.metodo 1,2,3

---

<div class="post-metadata">

**Author:** ![vogon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/34f0e0/32.png) [@vogon](https://www.ruby-forum.com/u/vogon)\
**Post date:** [August 23, 2011, 4:57pm UTC](https://www.ruby-forum.com/t/my-define-method/211011/2 "2011-08-23T16:57:52Z")

</div>

> self.class\_eval("def #{method\_name} \*args; #{ block.call() }; end;  
> Cos stai usando come corpo della funzione il _valore di ritorno_  
> della Proc, non funzioner.

> Il mio problema : come faccio dentro #{block.call( … ) a riferirmi  
> ad  
> \*args ?

args un Array, per utilizzarlo come elenco di argomenti per una  
funzione ti serve nuovamente l’asterisco. Esempio:

def print\_numbers(a, b, c)  
puts “#{a} #{b} #{c}”  
end

print\_numbers(1, 2, 3) # stampa 1 2 3  
numbers = [1, 2, 3]  
print\_numbers(numbers) # ArgumentError: wrong number of arguments (1 for  
3)  
print\_numbers(\*numbers) # stampa 1 2 3

---

<div class="post-metadata">

**Author:** ![vogon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/34f0e0/32.png) [@vogon](https://www.ruby-forum.com/u/vogon)\
**Post date:** [August 23, 2011, 7:18pm UTC](https://www.ruby-forum.com/t/my-define-method/211011/3 "2011-08-23T19:18:43Z")

</div>

2011/8/23 Vogon P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Salve ragazzi, studiando meta-programming in Ruby mi sono riproposto di  
> scrivere un metodo, my\_define\_method(), che emuli Module#define\_method o  
> che grosso modo, si comporti in maniera simile. ho pensato al seguente  
> snippet:

> class Module
> 
> def my\_define\_method method\_name, &block  
> self.class\_eval(“def #{method\_name} \*args; #{ block.call() }; end;  
> end;”)  
> end
> 
> end

non puoi farlo cos: block.call eseguita nello scope di  
my\_define\_method, mentre args nello scope del metodo che stai  
definendo.  
Non ti do la soluzione che mi viene in mente ma se leggi sotto ti do  
qualche hint. Fatto base: non credo possa funzionare usando class\_eval  
con una stringa come argomento 🙂

s  
p  
o  
i  
l  
e  
r

in assenza di define\_method o di Proc#to\_source _a occhio_ l’unica  
cosa che puoi fare pensare a come funziona l’invocazione di un  
metodo (ignorando l’ereditariet): c’ un nome (riferimento), del  
codice e una tabella che ti fa andare da uno all’altro, che locale  
per ogni classe. Ti tocca riprodurtelo in “userland”, un po’ come se  
volessi riscriverti “eval”[0].

[0] che ok, se consideri ripper & co lo puoi pure fare ma penso esuli  
dalla discussione

–  
twitter: @riffraff  
blog (en, it): www.riffraff.info [riffraff.blogsome.com](http://riffraff.blogsome.com)  
work: [cascaad.com](http://cascaad.com) [www.circleme.com](http://www.circleme.com)
