I hope you are doing well. I am new with Ruby and I don't really get what is the difference between a setter method and a method with a parameter. For example, let's say I have the following code:
module Popy
def self.friend
@friend
end
def self.friend=(new_friend)
@friend = new_friend
end
end
I understand that with the setter method called friend I set the @friend of Popy. But what is the difference if I put this method?
def self.friend!(new_friend)
@friend = new_friend
end
I have tried to search this on internet but can't find an answer. Thank you in advance! Have a great day.
CodePudding user response:
There is not much difference; the =
char is part of the method-name just like the !
. Readability is one issue - an exclamation mark is often used to draw attention to the method: "Watch out, something potentially risky is about to happen." I would be disappointed and a bit confused if friend!
turned out to be just a setter. Also , the =
allows Ruby to throw in some convenience methods like:
Popy.friend = "Ana"
Popy.friend = " maria"
p Popy.friend # => "Ana maria"
CodePudding user response:
From a semantic standpoint, there is no difference between a method named foo
, a method named bar
, a method named friend
, a method named friend!
, or a method named friend=
.
From a syntactic standpoint, though, a method whose name ends with =
can be called in a way that looks like assignment. In other words, the difference is in the syntax that can be used to call the methods:
Popy.friend = the_new_friend
Popy.friend!(the_new_friend)
But that is the only difference.
Note that your method named friend!
is not idiomatic Ruby: method names ending in a bang (!
) are only used when there is a pair of methods with the same name that do "roughly the same thing". In that case, the "more surprising" method of the pair of methods gets the bang.
In your case, you have a pair of methods with the same name (friend
). And the one which assigns the instance variable is surely the more surprising. But the thing is: those two methods don't do "roughly the same thing". In fact, they do the exact opposite of each other: one gets a value, the other sets a value.
Therefore, they should be named in a way that it makes it clear that they are opposites.
In a language like Java, the common idiom would be to name them getFriend
and setFriend
.
But in Ruby, the common idiom is to name them friend
and friend=
.