Ottenere il valore di una variabile di istanza dato il suo nome

In generale, come posso ottenere un riferimento a un oggetto il cui nome io sono in una stringa?

Più in particolare, ho un elenco di nomi di parametro (le variabili membro costruito in modo dinamico, quindi non posso fare riferimento a loro direttamente).

Ogni parametro è un oggetto che ha anche un from_s metodo.

Voglio fare qualcosa di simile (che ovviamente non funziona…):

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end
InformationsquelleAutor LK__ | 2009-07-02

 

2 Replies
  1. 172

    Più idiomatiche modo per raggiungere questo obiettivo è:

    some_object.instance_variable_get("@#{name}")

    Non c’è bisogno di utilizzare + o intern; Rubino di gestire questo bene. Tuttavia, se vi trovate a raggiungere in un altro oggetto e tirando fuori il suo ivar, c’è una discreta possibilità che hanno rotto l’incapsulamento.

    Se volete esplicitamente di accedere a un ivar, la cosa giusta da fare è quello di rendere una funzione di accesso. Si consideri il seguente:

    class Computer
      def new(cpus)
        @cpus = cpus
      end
    end

    In questo caso, se avete fatto Computer.new, si sarebbe costretti a utilizzare instance_variable_get per ottenere @cpus. Ma se si sta facendo questo, probabilmente significa per @cpus pubblica. Cosa si dovrebbe fare è:

    class Computer
      attr_reader :cpus
    end

    Ora si può fare Computer.new(4).cpus.

    Di notare che è possibile riaprire qualsiasi classe esistente e fare un privato ivar in un lettore. Dal momento che una funzione di accesso è solo un metodo, si può fare Computer.new(4).send(var_that_evaluates_to_cpus)

    • Non instance_variable_get(“@#{nome}”) restituisce il valore della variabile? Ho bisogno di un riferimento all’oggetto reale. Ho finito di riscrivere così invece di avere molte variabili + un array con i nomi in ordine ho voluto, ho messo i parametri stessi nella matrice (la decisione è stata se l’accesso variabili ogni volta cercando la matrice o ottimizzare avendo un ulteriore array con i loro nomi che potrebbero essere utilizzati solo quando necessario)
    • Nope: instance_variable_get(“@#{nome}”) restituisce l’oggetto vero e proprio.
    • Scoprire il thread inattivo per un po ‘ di chiarezza. L’esempio completo sarebbe: Computer di classe attr_read :cpu def nuovo(cpu) @cpus = cpu fine fine ?
    • “Tuttavia, se vi trovate a raggiungere in un altro oggetto e tirando fuori il suo ivar, c’è una discreta possibilità che hanno rotto l’incapsulamento.”. Come facciamo a rompere in un altro oggetto ivar ?.
  2. 9

    Per ottenere una variabile di istanza, dal nome di una variabile di istanza che fare:

    name = "paramName"
    instance_variable_get(("@" + name).intern)

    Restituisce il valore della variabile di istanza @paramName

    • Durante la creazione di una classe in modo dinamico, ho un array di variabile di istanza nomi (ho bisogno di questa lista perché ho bisogno di gestire in un certo ordine). Utilizzando questo nome, voglio ottenere un riferimento alla variabile.
    • Ho una stringa “paramName” e bisogno di un riferimento a @paramName
    • OK. Mi consiglia di modificare la tua domanda per dire esattamente quei due commenti.
    • Inoltre, questo non ha nulla a che fare con la deserializzazione. Il titolo potrebbe essere “il valore di una variabile di istanza dato il nome” o qualcosa del genere.
    • Si può sempre fare un Modulo e aggiungere :attr_reader varname quindi, è possibile accedere alle variabili in un più pulito, meno prolisso modo.

Lascia un commento