Recalling an instance variable in a virtual attribute with Ruby
So I am just starting to make my way through The Pragmatic Bookself's, "Programming Ruby 1.9 (3rd Edition)" and I've come across some code that I need a little clarification on.
If you own the book, it's in Chapter 3's, "Classes, Objects, and Variables," specifically in the section about virtual attributes.
Basically, a class is defined with an initializer that sets a couple of instance variables, one of which is @price
. That variable ha开发者_开发百科s an accessor / mutator created with attr_accessor like so:
attr_accessor :price
That class also has a virtual attribute called, price_in_cents
which simply returns the value from this line:
Integer(price*100 + 0.5)
Now my question is why is price
in the virtual attribute not prefixed with an @
? It is clearly dealing with an instance variable. Executing the code without the @
works just the same as with; why is that?
P.S. Sorry for not just posting the code wholesale—given that this is a question about code in a book, I wasn't sure what legal right I'd have to post.
That's a receiverless message send.
In Ruby, the receiver self
is implicit: you can leave it out if you want to. So, price
is basically the same as self.price
(ignoring access restrictions).
In other words, it's calling the method price
you defined with attr_accessor
.
You can easily confirm that that two references (price
and @price
) point to the same objects:
#!/usr/bin/env ruby
class MyPrice < Object
attr_accessor :price
def initialize(price = 0)
@price = price
end
def price_in_cents
Integer(price * 100 + 0.5)
end
def objects
puts "@price.object_id: #{@price.object_id}"
puts "price.object_id: #{price.object_id}"
end
end
p = MyPrice.new(150)
p.objects
puts "price in cents: #{p.price_in_cents}"
Which produces:
# ./price.rb
@price.object_id: 301
price.object_id: 301
price in cents: 15000
The fact that price
and @price
both have an object id of 301 shows you that they are both references to a single object.
This question was posted years back but just in case anybody is running into similar issues like the example on top.
I don't think self.price has anything to do with attr_accessor, self.price only applies to the class where attr_accessor becomes a shortcut for instance variable. You don't need to input the '@' in front of the attr_accessor because it acts as a shortcut for your setters and getters if you are familiar to Java. Part of Ruby's easy going way of getting things done faster more eloquently.
精彩评论