Can Someone Explain This to Me?

Discussion in 'Ruby' started by Ron Green, Aug 20, 2008.

  1. Ron Green

    Ron Green Guest

    [Note: parts of this message were removed to make it a legal post.]

    class Body
    @feet = 2
    puts "We have #{@feet} feet"
    def initialize

    end
    def report
    puts "We have #{@feet} feet"
    end
    end

    b=Body.new
    b.report

    Why is it in the above class the first puts prints correctly but the second
    puts doesn't have a value for the instance variable?
     
    Ron Green, Aug 20, 2008
    #1
    1. Advertisements

  2. When you have a variable with @ in front, it's an instance variable of
    the object which
    is self when the variable is created. In your case, @feet is created
    when self is the class
    object Body. It is not an instance variable of an object of class
    Body, as it would if you
    did this:


    irb(main):001:0> class Body
    irb(main):002:1> def initialize
    irb(main):003:2> @feet = 3
    irb(main):004:2> end
    irb(main):005:1> def report
    irb(main):006:2> puts "We have #{@feet} feet"
    irb(main):007:2> end
    irb(main):008:1> end
    => nil
    irb(main):009:0> Body.new.report
    We have 3 feet

    Classes are also objects themselves and can have instance variables
    just as any other object:

    irb(main):010:0> class Body
    irb(main):011:1> @feet = 2
    irb(main):012:1> class << self
    irb(main):013:2> attr_accessor :feet
    irb(main):014:2> end
    irb(main):015:1> end
    => nil
    irb(main):016:0> Body.feet
    => 2
    irb(main):017:0> class Body
    irb(main):018:1> def self.report
    irb(main):019:2> puts "We have #{@feet} in the class Body"
    irb(main):020:2> end
    irb(main):021:1> end
    => nil
    irb(main):022:0> Body.report
    We have 2 in the class Body

    Now, the variable @feet above is a different object from the @feet in
    my first example. In fact you can have both and they won't interfere.
    You just have to understand who is "self" in each context:

    irb(main):023:0> class Body
    irb(main):024:1> @feet = 2
    irb(main):025:1> class << self
    irb(main):026:2> attr_accessor :feet
    irb(main):027:2> def class_report
    irb(main):028:3> "We have #{@feet} in class Body"
    irb(main):029:3> end
    irb(main):030:2> end
    irb(main):031:1> def initialize
    irb(main):032:2> @feet = 3
    irb(main):033:2> end
    irb(main):034:1> def report
    irb(main):035:2> "We have #{@feet} in the instances of class Body"
    irb(main):036:2> end
    irb(main):037:1> end
    => nil
    irb(main):038:0> Body.feet
    => 2
    irb(main):039:0> Body.report
    We have 2 in the class Body
    => nil
    irb(main):040:0> b = Body.new
    => #<Body:0xb7c2c4fc @feet=3>
    irb(main):041:0> b.report
    => "We have 3 in the instances of class Body"


    Hope this helps,

    Jesus.
     
    Jesús Gabriel y Galán, Aug 20, 2008
    #2
    1. Advertisements

  3. Well, in this case, you're defining an instance variable... on Body, the
    class:
    You see, classes are objects, too. You can treat them like normal objects:

    b = Body
    c = b.new

    The normal way to do what I think you're wanting to do here is:

    class Body
    def initialize
    @feet = 2
    end
    end

    By the way, you can leave out initialize if you have nothing to initialize.

    Of course, if you're only supporting humans, you could do this:

    class Body
    FEET = 2
    def report
    puts "We have #{FEET} feet"
    end
    end

    One more thing: I don't often use instance variables directly. That gives me
    more flexibility -- I can do something like this:

    class Body
    attr_reader :feet
    def initialize
    @feet = 2
    end
    def report
    puts "We have #{feet} feet"
    end
    end

    That way, I could change to using a constant without touching the "report"
    method. The next version would look like this:

    class Body
    FEET = 2
    def feet
    FEET
    end
    ...
    end

    But it's getting a bit silly talking about feet, so I'll stop.
     
    David Masover, Aug 21, 2008
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.