No, there is only class_variable_get
, instance_variable_get
and const_get
. There is no local_variable_get
. But it wouldn't make sense anyway: local variables are local to the current method body, module body, class body or script body, that's why they are called "local" variables, after all! You simply cannot access them from another method.
Is there a way to do:
test = "heyas"
some_method_here("test") #=> "heyas"
No, there is no way to do this. And there cannot possibly be a way to do it. test
is a local variable, which means it only exists in the current script body. It does not exist inside the body of some_method_here
. That's the whole point of local variables: you cannot ever, under any circumstances, access them from somewhere else.
Regarding your comment on another answer:
def my_func(str)
var_a = 'hey'
var_b = 'ah'
return some_method_here(str)
end
#=> should return the corresponding variable's value, e.g. my_func('var_a')
#=> 'hey'
Again, this cannot possibly work, since the whole point of local variables is that they cannot be accessed from anywhere else.
But there is a pretty simple variation which does exactly what you want:
def my_func(str)
{
'var_a' => 'hey',
'var_b' => 'ah'
}[str]
end
#=> should return the corresponding variable's value, e.g. my_func('var_a')
#=> 'hey'
This can of course be further simplified to:
my_func = {'var_a' => 'hey', 'var_b' => 'ah'}
#=> should return the corresponding variable's value, e.g. my_func['var_a']
#=> 'hey'
Given that you can only pass in a limited number of different options, it's probably better to use symbols instead:
my_func = {var_a: 'hey', var_b: 'ah'}
#=> should return the corresponding variable's value, e.g. my_func[:var_a]
#=> 'hey'
What you are asking is basically: pass in a key, get a value out. That's exactly what a Hash
is.
EDIT: After the revised question, this is the best that I could come up with:
def validate(u, e, p)
local_variables.zip(local_variables.map {|var|
eval(var.to_s)
}).each {|var, val|
Validations.send(:define_singleton_method, var) { val }
}
end
However, I think there is something seriously wrong with the design. You overwrite singleton methods of User::Validations
based on different instances of User
. By the very definition of singleton method, there can only ever be one copy of those in the system. But you have many different instances of User
, and every time you call User#validate
it will overwrite the only copies of User::Validations.u
, User::Validations.e
and User::Validations.p
at which point they will start to behave completely differently for the entire system.
In other words, you are changing the behavior of the entire system based on a single instance. And there can be many instances and every time, the behavior of the system changes.
That just can't be right.
u1 = User.new
u1.validate('u1', :e1, 1)
p User::Validations.u, User::Validations.e, User::Validations.p
# => 'u1'
# => :e1
# => 1
u2 = User.new
u2.validate('U2', :E2, 2.0)
# => warning: method redefined; discarding old u
# => warning: method redefined; discarding old e
# => warning: method redefined; discarding old p
# ^^^^^^^^^^^^^^^^
# Oops!
p User::Validations.u, User::Validations.e, User::Validations.p
# => 'U2'
# => :E2
# => 2.0
# ^^^
# Completely different results for the exact same arguments