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
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 are those pipe symbols for in Ruby?
(7 answers)
Closed 2 years ago.
What is the | | around profile below called, what does it mean, and why it is after do? I thought do is followed by a loop block or so.
ticks = get_all[0...MAX].map do |profile|
# ...
end
it's like a foreach, so profile will be a different value in each of the functions calls, one function call per element in get_all.
see this:
my_array = [:uno, :dos, :tres]
my_array.each do |item|
puts item
end
They are part of the syntax for defining a block. The way I like to explain it is that the pipes look like a slide and those variables inside the pipes "slide" down into the block of code below them.
Essentially the variables in the pipes are available to the block. In the case of iteration the variable would represent an element in whatever you are iterating over.
I'll use this example to try to explain the concept to you.
friends = ["James", "Bob", "Frank"]
friends.each { |friend| puts friend }
James
Bob
Frank
So here, we have an array of our friends: James, Bob, and Frank.
In order to iterate over them, we call the #each method on the array. The method will start with the first item in my array and call the block on it.
Essentially, the item that I'm currently iterating over is passed to the variable inside of the two pipe characters. You can call it |buddy| and change the block to { |buddy| puts buddy } and it would still do the same thing.
The pipe characters delimit the parameter list of a block definition just like parentheses delimit the parameter list of a method definition. So, in this code snippet:
def foo(bar, baz) end
some_method_that_takes_a_block do |bar, baz| end
The parentheses and the pipes have the exact same purpose.
This question already has an answer here:
Why isn't `method=` treated the same as any other method?
(1 answer)
Closed 6 years ago.
Would someone care to explain why in older versions of Ruby, the result of the assignment was the value returned by the attribute-setting method, but after Ruby 1.8, the value of the assignment is always the value of the parameter; the return value of the method is discarded. In the code that follows, older versions of Ruby would set result to 99. Now result will be set to 2.
class Test
def val=(val)
#val = val
return 99
end
end
t = Test.new
result = (t.val = 2)
result # => 2
What was the reasoning behind this change?
It's not uncommon to chain assignments together when you want to assign the same value to multiple variables. This is even more common in other languages.
#user_id = user.id = next_user_id
But what happens when you aren't thinking about that, and so the return value isn't the same as the input value?
class User
def id=(name)
#id = name
#modified = true
end
def modified?
#modified
end
end
This code will work totally fine until one day when you go drop it in an assignment chain like the above, when all of a sudden you'll get unexpected results.
So, the interpreter does some sort of voodoo and ensures that the RHS of the assignment is the return value, discarding the actual return value.
Assignments always evaluate to the assigned value. That's a simple and consistent rule, both consistent within Ruby itself, as well as consistent with most other expression-based programming languages.
Everything else would be an inconsistent special case, and those are bad.
This question already has answers here:
How to understand symbols in Ruby
(11 answers)
Closed 10 years ago.
class A
def test
"Test from instance"
end
class << self
def test
"Test from class"
end
end
end
p A.send(:test) # "Test from class"
p A.new.method(:test).call # "Test from instance"
Here symbol works as expected, but here:
s="test"
s1=:s
p s1 # :s
why :s is printed here?? I dont understand the reason behind it.
Can anyone please explain for me ?
Symbols are sort of lightweight strings (though they are not strings). The send() and method() methods can take strings or symbols; one is converted to the other in the inner workings (not sure which) and then ruby executes the method with the matching name. Hence A.send(:text) is equivalent to A.text(). If you had a variable named methodName = :text, you could do A.send(methodName) but not A.methodName().
Symbols are not variables, so you can't assign a value to a symbol. In your example, the symbol :s is unrelated to the variable s (despite the fact that they have the same "name", preceding it with a colon makes it a symbol instead of a variable). You're assigning a string value to the variable s but telling it to print the symbol :s, which it does.
Symbols are just a special kind of stringlike value that's more efficient for the runtime to deal with than a regular string. That's it. They aren't methods or variables or anything like that.
When you do A.send(:test), all you are doing is saying "hey, A, call the method named 'test'". You aren't sending the method itself, just the name; it's the logic inside send that is responsible for looking up the actual method to call.
The same thing goes when you ask for method with A.new.method(:test). All you are passing to method is the name "test", not the method defined with that name. It's up to method to use the name and find the actual method so it can return it, and it's that return value - a Method object - that you are doing call on. You can't do call on a Symbol like :test, because it's just a name.
From https://stackoverflow.com/a/1255362/509710:
p foo does puts foo.inspect, i.e. it prints the value of inspect instead of to_s, which is more suitable for debugging (because you can e.g. tell the difference between 1, "1" and "2\b1", which you can't when printing without inspect).
s="test"
s1=:s
p :s.object_id #137448
p s.object_id #77489950
p s1.object_id #137448
I have understand it now. I was assigning a symbol but expecting a string.
You set the value of s1 to be :s, so why would you expect it to return anything different?
If you look at the ruby API for the Object class, you will see both Object#send and Object#method take a symbol as a parameter, so the top example is also totally expected.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is the difference or value of these block coding styles in Ruby?
# This works
method :argument do
other_method
end
# This does not
method :argument {
other_method
}
Why?
It seems like the interpreter is confused and thinks that the { ... } is a hash.
I always get angry when an interpreter can't understand a code that is actually valid. It resembles PHP that had many problems of this kind.
It doesn't think it's a hash - it's a precedence issue. {} binds tighter than do end, so method :argument { other_method } is parsed as method(:argument {other_method}), which is not syntactically valid (but it would be if instead of a symbol the argument would be another method call).
If you add parentheses (method(:argument) { other_method }), it will work fine.
And no, the code is not actually valid. If it were, it would work.