web-dev-qa-db-fra.com

Utilisation d'une chaîne en tant que variable au moment de l'exécution

J'ai une chaîne qui a été créée à l'exécution. Je veux utiliser cette chaîne en tant que variable pour y stocker des données. Comment puis-je convertir la chaîne en un nom de variable?

36
Satyam Gautam

Si vous pouvez pardonner un signe @ devant le nom de la variable, ce qui suit fonctionnera:

variable_name = ... # determine user-given variable name
instance_variable_set("@#{variable_name}", :something)

Cela créera une variable nommée @whatever, avec sa valeur définie sur :something. Le :something pourrait bien être ce que vous voulez. Cela semble fonctionner dans une portée globale, en déclarant une instance spontanée Object qui lie tout (je ne peux pas trouver de référence pour cela).

La méthode instance_variable_get vous permettra de récupérer une valeur par son nom de la même manière.

instance_variable_get("@#{variable_name}")
54
Andres Jaan Tack

Plutôt que de le faire directement, pourquoi ne pas utiliser un hash à la place. La chaîne serait la clé et la valeur que vous souhaitez stocker serait la valeur. Quelque chose comme ça:

string_values = { }
some_string = params[:some_string]       # parameter was, say "Hello"
string_values[some_string] = 42
string_values                            # { 'Hello' => 42 }
some_number = string_values[some_string]
some_number                              # 42

Cela a quelques avantages. Premièrement, cela signifie que vous ne faites rien de magique qui puisse être difficile à comprendre plus tard. Deuxièmement, vous utilisez un langage Ruby très courant utilisé pour des fonctionnalités similaires dans Rails.

12
Tim Sullivan

Vous pouvez utiliser eval() pour cela à condition que vous ayez d'abord déclaré votre variable:

>> foo = []
>> eval("foo")[1] = "bar"
>> foo[1]
=> "bar"

Voici les docs .

8
Gordon Wilson

Je ne veux pas être négatif, mais faites attention. Ruby vous offre de nombreuses fonctionnalités pour la programmation hautement dynamique telles que define_method, stocker des blocs sous la forme d'objets Proc à appeler ultérieurement, etc. Généralement, ces codes sont plus propres et beaucoup plus sûrs. Utiliser eval() dans 99% des cas est une erreur.

Et n'utilisez jamais eval() sur une chaîne contenant une entrée soumise par l'utilisateur. 

5
Jason Watkins

Maintenant, en utilisant simplement la méthode instance_variable_set, vous pouvez créer une variable d'instance au moment de l'exécution.

instance_variable_set('@' + 'users', User.all)
3
uma

Comme le dit Jason Watkins, de nombreuses personnes pourraient utiliser promptement eval (), ce qui constituerait une grave erreur. La plupart du temps, vous pouvez utiliser la technique décrite par Tack si vous avez pris soin d’utiliser une variable d’instance de classe au lieu d’une variable locale.

Les variables locales ne sont généralement pas récupérables. Tout ce qui porte le préfixe @ ou @@ est facilement récupérable.

0
tadman