How to dynamically create a local variable?

后端 未结 4 2212
温柔的废话
温柔的废话 2020-11-22 03:46

I have a variable var = \"some_name\" and I would like to create a new object and assign it to some_name. How can I do it? E.g.

var         


        
4条回答
  •  梦谈多话
    2020-11-22 04:41

    Although, as others have pointed out, you cannot dynamically create local variables in Ruby, you can simulate this behavior to some degree using methods:

    hash_of_variables = {var1: "Value 1", var2: "Value 2"}
    
    hash_of_variables.each do |var, val|
      define_method(var) do
        instance_variable_get("@__#{var}")
      end
      instance_variable_set("@__#{var}", val)
    end
    
    puts var1
    puts var2
    var1 = var2.upcase
    puts var1
    

    Prints:

    Value 1
    Value 2
    VALUE 2
    

    Some libraries combine this technique with instance_exec to expose what appear to be local variables inside a block:

    def with_vars(vars_hash, &block)
      scope = Object.new
      vars_hash.each do |var, val|
        scope.send(:define_singleton_method, var) do
          scope.instance_variable_get("@__#{var}")
        end
        scope.instance_variable_set("@__#{var}", val)
      end
      scope.instance_exec(&block)
    end
    
    with_vars(a: 1, b:2) do
      puts a + b
    end
    

    Prints: 3

    Be aware though that the abstraction is by no means perfect:

    with_vars(a: 1, b:2) do
      a = a + 1
      puts a
    end
    

    Results in: undefined method `+' for nil:NilClass. This is because a= defines an actual local variable, initialized to nil, which takes precedence over the method a. Then a.+(1) gets called, and nil doesn't have a + method, so an error is thrown.

    So while this method is pretty useful for simulating read-only local variables, it doesn't always work well when you try to reassign the variable inside the block.

提交回复
热议问题