This question already has answers here:
How to dynamically create a local variable?
(4 answers)
Closed 3 years ago.
Not sure what am I doing wrong here or missing.
avar = 'test'
test_bvar = 'passed'
finalanswer = send "#{avar}_bvar"
puts " #{finalanswer}"
thanks,
The send method is used to call a method by name programmatically. Since your test_bvar is not a method but a local variable, you need to refactor it like this:
def test_bvar
"passed"
end
avar = "test"
finalanswer = send "#{avar}_bvar"
puts " #{finalanswer}"
Then you will reach your aim.
You are defining test_bvar as a local variable:
test_bvar = 'passed'
and you're trying to call it like a method:
send "test_bvar"
If you want to make this a method, do as #Mack94's answer suggests.
Related
This question already has answers here:
What does ||= (or-equals) mean in Ruby?
(23 answers)
Closed 7 years ago.
I'm still pretty green when it comes to Ruby and am trying to figure out what this is doing:
command_windows.each {|window| window.hidden ||= window.open? }
The command_windows variable appears to be an array of objects. If someone could explain to me what this line of code means, particularly what the ||= symbol is I would appreciate it.
foo ||= "bar" is the equivalent of doing foo || foo = "bar".
As Mischa explained, it checks for a falsy value before assigning.
In your case, you could think of it as:
command_windows.each {|window| window.hidden || window.hidden = window.open? }
which is another way of saying
command_windows.each {|window| window.hidden = window.open? unless window.hidden }
The ||= operator is used to assign new value to variable. If something was assigned to it before it won't work. It is usually used in hashes, so you don't have to check, if something is already assigned.
This question already has answers here:
What does the equal ('=') symbol do when put after the method name in a method definition?
(4 answers)
Closed 8 years ago.
I am sorry if this is a noob question, but I can't seem to find the answer neither in stackoverflow, nor anywhere else. The code is:
def full_name=(new_full_name)
# stuff
end
When I define it in the console, and try to evoke it:
full_name # nil
full_name # [hangs, needs ^C]
full_name= arg # works like normal function
full_name # works again with no arguments, as if I passed the previous argument
So, what is going on?
Thanks.
A method ending with an = defines a setter. When defining a setter like that, ruby will always return the method argument regardless of the body definition when you call the setter.
You can then use object.full_name= "Daniel" which returns => "Daniel"
Some other common appendices with your example:
The question mark, e.g.
has_full_name?
is expected to return a boolean value if the object has a full_name
The exclamation mark, e.g.
revert_full_name!
is expected to revert the full_name variable of the object
revert_full_name
in contrast is expected to return the reverted full_name variable but not to change it in the object
This question already has answers here:
How to dynamically create a local variable?
(4 answers)
Closed 7 years ago.
I have list like this:
list = ["test1","test2","test3"]
I want to assign three associated variables with values. Like:
test1_var = "test1"
test2_var = "test2"
test3_var = "test3"
I ran a loop like this and got an error:
list.each { |x| eval(x+"_var") = x}
What is the correct way to do this?
As far as I can tell, it is only possible to dynamically set instance variables and not local variables. So if this is inside a class of some sort, then this will work. If you absolutely don't want them as instance variables in then end, then just assign each to a local version.
list = ["test1","test2","test3"]
list.each { |t| instance_variable_set("##{t}_var".to_sym, t) }
Here is the documentation for instance_variable_set:
http://www.ruby-doc.org/core-1.9.3/Object.html#method-i-instance_variable_set
The block has a different scope of its own. So if you create a local variable within the block, it will not persist beyond the execution of list.each block. Also there are other restrictions as well.
This is almost impossible as per this blog post: http://blog.myrecipecart.com/2010/06/ruby-19-dynamic-creation-of-local.html
This question already has answers here:
Setter method (assignment) with multiple arguments
(2 answers)
Closed 8 years ago.
My method is:
def title=(text, sub_text = 'another piece of text')
self.title = text + sub_text
end
Somewhere else in my code, I do something like:
subtext = "enhusiasts"
title = "hello ruby "
How can I pass subtext to the title setter function so that my title becomes:
hello ruby enthusiasts
Do I have to write a separate function to use this setter?
While there is nothing particularly special about writer methods ending in =, the syntax of the language will not allow them to be called with multiple arguments. You can use send:
object.send :title=, title, subtext
That is not a clean solution, though. Also, your title= method is recursive; you should be setting an instance variable directly.
I recommend something like this:
attr_writer :text, :sub_text
def title
text + sub_text
end
# ...
object.text = 'hello ruby '
object.sub_text = 'enthusiasts'
object.title
# => "hello ruby enthusiasts"
You can call it using self.send('title=', 'string1') or self.send('title=', 'string1', 'string2').
But you cannot just call it the usual way title = 'string1', 'string2'. That is because the parser wont allow it. When = is present, the statement is expected to be in identifier = expression format.
Better you don"t you name your function with the = in such case.
Also it is recommended and is the convention that you concat your string by interpolation i.e.:
self.title = "#{text} #{sub_text}" instead of self.title = text + sub_text.
This prevents error being generated when text is nil.
This question already has answers here:
How to call methods dynamically based on their name? [duplicate]
(5 answers)
Closed 8 years ago.
How can I use a string as a method call?
"Some Word".class #=> String
a = "class"
"Some World".a #=> undefined method 'a'
"Some World"."#{a}" #=> syntax error, unexpected tSTRING_BEG
Object#send
>> a = "class"
>> "foo".send(a)
=> String
>> a = "reverse"
>> "foo".send(a)
=> "oof"
>> a = "something"
>> "foo".send(a)
NoMethodError: undefined method `something' for "foo":String
If you want to do a chain, can also use Object#eval
>> a = "foo"
=> "foo"
>> eval "a.reverse.upcase"
=> "OOF"
If you have a string that contains a snippet of ruby code, you can use eval. I was looking for question with that answer when I landed here. After going off and working it out (thanks ProgrammingRuby), I'm posting this in case others come here looking for what I was looking for.
Consider the scenario where I have a line of code. here it is:
NAMESPACE::method(args)
Now consider the scenario where that is in a string variable
myvar = "NAMESPACE::method(args)"
Using send(myvar) does not execute the command. Here is how you do it:
eval(myvar)