开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜