2013-05-17 11 views
5

So che posso fare:È possibile accedere agli argomenti delle parole chiave come un hash in Ruby?

class Parent 
    def initialize(args) 
    args.each do |k,v| 
     instance_variable_set("@#{k}", v) 
    end 
    end 
end 
class A < Parent 
    def initialize(attrs) 
    super(attrs) 
    end 
end 

Ma vorrei usare argomenti chiave per rendere più chiaro quale metodo chiavi di hash può accettare (e hanno convalida dicendo che questa chiave non è supportato).

Quindi posso scrivere:

class A 
    def initialize(param1: 3, param2: 4) 
    @param1 = param1 
    @param2 = param2 
    end 
end 

Ma è possibile scrivere qualcosa di più breve, invece di @x = x; @y = y; ... per inizializzare variabili di istanza da argomenti chiave passati? È possibile accedere agli argomenti delle parole chiave passati come un hash?

+0

Qual è lo scopo dell'utilizzo di un hash se si dispone di argomenti di parole chiave? –

+1

@DaveNewton, accesso programmatico a tutti gli argomenti della parola chiave contemporaneamente. – Dogbert

+0

@DaveNewton per semplificare l'inizializzazione delle variabili di istanza con gli stessi nomi dei tasti degli argomenti delle parole chiave –

risposta

4

Non qualcosa che raccomando di usare (perché eval!), Ma questo è l'unico modo a cui riesco a pensare, poiché non penso che ci sia un modo per ottenere il valore di una variabile locale senza eval.

class A 
    def initialize(param1: 3, param2: 4) 
    method(__method__).parameters.each do |type, name| 
     if type == :key 
     instance_variable_set "@#{name}", eval("#{name}") 
     end 
    end 
    end 
end 

p A.new param1: 20, param2: 23 
p A.new 

uscita:

#<A:0x007fd7e21008d0 @param1=20, @param2=23> 
#<A:0x007fd7e2100218 @param1=3, @param2=4> 

method restituisce un oggetto Method per il passato in simbolo, __method__ restituisce il nome del metodo corrente e Method#parameters restituisce un array che descrive i parametri del metodo accetta. Qui imposto solo i parametri che hanno il tipo :key (params nominati).

+0

Grazie, non sapevo su "__method__". Volevo ridurre la quantità del mio codice e renderlo più leggibile, ma questo non lo rende più leggibile poiché sembra che non possa spostare questo codice in 'Parent' –

+0

' eval ("# {nome}") 'deve essere uguale per 'nome', no? Perché hai bisogno di 'eval'? – akostadinov

Problemi correlati