Reputation: 184
I have a setter and a getter method for attribute :isbn
on class Book
:
class Book
attr_accessor :isbn
end
book01
is an instance of Book
:
book01 = Book.new
Which of these is the preferred way when setting an instance attribute?
book01.isbn=("9876")
book01.isbn= "9876"
book01.isbn = "9876"
Why does this not work as an option?
book01.isbn("9876")
# => ArgumentError: wrong number of arguments (1 for 0)
Upvotes: 2
Views: 544
Reputation: 8424
In your example:
book01.isbn=("9876")
book01.isbn= "9876"
book01.isbn = "9876"
The last 2 examples are 'syntactic sugar', which are things that technically aren't proper syntactically but are kept in the language because they keep the code cleaner. The first example is the only way that would work if Ruby didn't support syntactic sugar. Why?
Because attr_acccessor :isbn behind the hood creates the following code for you:
def isbn
@isbn
end
def isbn=(new_isbn)
@isbn = new_isbn
end
These are 2 totally different methods, this might be confusing because the only difference in name is the = sign. But that doesn't mean anything, and doesn't change the fact they are totally different methods. So with:
book01.isbn=("9876")
you're actually calling def isbn=(new_isbn) which is a method, nothing more, nothing else. And with:
book01.isbn= "9876"
book01.isbn = "9876"
you're just calling the SAME method, just using 'syntactic sugar'. Behind the hood, Ruby sees all of these 2 as:
book01.isbn=("9876")
Can you guess why this code will not work?
book01.isbn("9876")
Because, as we saw earlier, behind the hood Ruby creates 2 methods. The first method doesn't accept ANY arguments, therefore, you get the error you're getting (Ruby is just telling you, I expected 0 arguments, and you provided 1, therefore I raised ArgumentError).
Upvotes: 3