attr_reader

Discussion in 'Ruby' started by 7stud 7stud, Sep 1, 2007.

  1. 7stud 7stud

    7stud 7stud Guest

    On p. 30-31 of "Programming Ruby (2nd ed)", there is this example:

    class Song
    attr_reader :name, :artist, :duration
    end

    and the text says:

    "The corresponding instance variables, @name, @artist, and @duration,
    will be created for you."

    But I discovered that I still have to define an initialize method to
    create objects:

    class Song
    attr_reader :x, :y, :z

    def initialize(x, y, z)
    @x = x
    @y = y
    @z = z
    end
    end

    s = Song.new(10, 20, 30)
    puts s.x

    So, it seems like initialize is what creates the instance variables.
    Or, does attr_reader somehow do its thing before initialize is called?
    If so, why is it considered important to know that attr_reader creates
    the instance variables instead of initialize?
    --
    Posted via http://www.ruby-forum.com/.
    7stud 7stud, Sep 1, 2007
    #1
    1. Advertising

  2. 7stud 7stud

    7stud *** Guest

    Peña, Botp wrote:
    > From: 7stud 7stud [mailto:]
    > # "The corresponding instance variables, @name, @artist, and @duration,
    > # will be created for you."
    >
    > that should read: "The corresponding instance variable getter and setter
    > methods will be created for you."
    >


    Huh? As far as I can tell, no setter methods are created:

    class Song
    attr_reader :x, :y, :z

    def initialize(x, y, z)
    @x = x
    @y = y
    @z = z
    end
    end

    s = Song.new (10, 20, 30)
    puts s.x
    s.x = 40

    --output:--
    10
    r1test.rb:22: undefined method `x=' for #<Song:0x253c8 @y=20, @x=10,
    @z=30> (NoMethodError)


    >
    > #So, it seems like initialize is what creates the instance variables.
    >
    > not really.
    >
    > irb(main):097:0> class Song2
    > irb(main):098:1> attr_accessor :x, :y
    > irb(main):099:1> end
    > => nil
    >
    > note, no initialization there
    >


    My program has no attr_accessor line (the book hasn't mentioned
    attr_accessor yet). Your saying the initialize method in my program
    doesn't create the instance variables? What does?

    --
    Posted via http://www.ruby-forum.com/.
    7stud ***, Sep 1, 2007
    #2
    1. Advertising

  3. RnJvbTogN3N0dWQgKioqIFttYWlsdG86ZG9sZ3VuQGV4Y2l0ZS5jb21dIA0KIyBIdWg/ICBBcyBm
    YXIgYXMgSSBjYW4gdGVsbCwgbm8gc2V0dGVyIG1ldGhvZHMgYXJlIGNyZWF0ZWQ6DQojIA0KIyBj
    bGFzcyBTb25nDQojICAgICBhdHRyX3JlYWRlciA6eCwgOnksIDp6DQoNCnNvcnJ5LCBpIG1pc3Jl
    YWQgeW91ciBwb3N0LiAgYXR0cl9yZWFkZXIgb25seSBnaXZlcyBnZXR0ZXJzLg0KDQojIE15IHBy
    b2dyYW0gaGFzIG5vIGF0dHJfYWNjZXNzb3IgbGluZSAodGhlIGJvb2sgaGFzbid0IG1lbnRpb25l
    ZCANCiMgYXR0cl9hY2Nlc3NvciB5ZXQpLiAgWW91ciBzYXlpbmcgdGhlIGluaXRpYWxpemUgbWV0
    aG9kIGluIG15IHByb2dyYW0gDQojIGRvZXNuJ3QgY3JlYXRlIHRoZSBpbnN0YW5jZSB2YXJpYWJs
    ZXM/ICANCg0KbXkgZW5nbGlzaCBpcyBwb29yLiBzb3JyeS4gaW5pdGlhbGl6ZSB3aWxsIGNyZWF0
    ZSBpdCwgYnV0IGl0J3Mgbm90IHRoZSBvbmx5IHdheS4geW91IGNhbiBjcmVhdGUgeW91ciBvd24g
    c2V0dGVycy4NCg0Ka2luZCByZWdhcmRzIC1ib3RwDQoNCg==
    Peña, Botp, Sep 1, 2007
    #3
  4. 7stud 7stud

    7stud *** Guest

    7stud ***, Sep 1, 2007
    #4
  5. 7stud 7stud

    7stud *** Guest

    Actually, I think attr_reader does create the instance variables:

    class Song
    attr_reader :name, :artist, :duration
    end

    song = Song.new

    puts song.name
    puts song.artist
    puts song.duration

    puts song.fake

    --output:---
    nil
    nil
    nil
    r1test.rb:18: undefined method `fake' for #<Song:0x253c8>
    (NoMethodError)
    --
    Posted via http://www.ruby-forum.com/.
    7stud ***, Sep 2, 2007
    #5
  6. 7stud 7stud

    7stud *** Guest

    And this confirms it:

    class Song
    #attr_reader :name, :artist, :duration
    end

    song = Song.new

    puts song.name
    puts song.artist
    puts song.duration

    puts song.fake

    --output:---
    r1test.rb:8: undefined method `name' for #<Song:0x25648> (NoMethodError)
    --
    Posted via http://www.ruby-forum.com/.
    7stud ***, Sep 2, 2007
    #6
  7. On 9/1/07, 7stud *** <> wrote:
    > Actually, I think attr_reader does create the instance variables:
    >
    > class Song
    > attr_reader :name, :artist, :duration
    > end
    >
    > song = Song.new
    >
    > puts song.name
    > puts song.artist
    > puts song.duration


    Nope. It's just that an undefined instance variable is treated as
    though it were nil. Try this on for size:

    puts song.name
    puts song.instance_variables
    Logan Capaldo, Sep 2, 2007
    #7
  8. 7stud 7stud

    7stud -- Guest

    Logan Capaldo wrote:
    > On 9/1/07, 7stud *** <> wrote:
    >> puts song.duration

    > Nope. It's just that an undefined instance variable is treated as
    > though it were nil.


    Then why isn't song.fake treated as though it were nil?


    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 2, 2007
    #8
  9. 7stud 7stud

    7stud -- Guest

    Logan Capaldo wrote:
    >Try this on for size:
    >
    > puts song.name
    > puts song.instance_variables


    lol. I looked up instance_variables in "Programming Ruby (2d ed)" and it
    says:

    "Note that simply defining an accessor does not create the corresponding
    instance variables."

    That statement contradicts the statement I posted earlier on p. 31 of
    the same book.

    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 2, 2007
    #9
  10. 7stud -- wrote:
    > Logan Capaldo wrote:


    > > Nope. It's just that an undefined instance variable is treated as
    > > though it were nil.

    >
    > Then why isn't song.fake treated as though it were nil?


    song.fake isn't an instance variable, it's a method (well actually it's not,
    it's nothing, but if it did exists, it'd be a method).
    attr_reader :duration creates the method duration, which returns the
    instance variable @duration, even if the latter doesn't exist yet.
    song.fake throws an error because there is no method fake, independantly
    of whether or not an instance variable @fake exists.
    song.instance_variable_get "@fake" would return nil.

    HTH,
    Sebastian
    --
    Jabber:
    ICQ: 205544826
    Sebastian Hungerecker, Sep 2, 2007
    #10
  11. 7stud 7stud

    7stud -- Guest

    Sebastian Hungerecker wrote:
    > attr_reader :duration creates the method duration, which returns the
    > instance variable @duration, even if the latter doesn't exist yet.
    > song.fake throws an error because there is no method fake


    Ok. Thanks for the explanation.
    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Sep 2, 2007
    #11
  12. 7stud 7stud

    Ken Bloom Guest

    On Sun, 02 Sep 2007 08:53:59 +0900, 7stud *** wrote:

    > And this confirms it:
    >
    > class Song
    > #attr_reader :name, :artist, :duration
    > end
    >
    > song = Song.new
    >
    > puts song.name
    > puts song.artist
    > puts song.duration
    >
    > puts song.fake
    >
    > --output:---
    > r1test.rb:8: undefined method `name' for #<Song:0x25648> (NoMethodError)


    There are two different things going on with attribute readers:

    attr_reader :foo creates a *method* to access the instance variable @foo.
    When you get a NoMethodError, because there's no such method.

    Supposing you create an instance variable @bar in some method, such as
    initailze, but have no attr_reader for it. You'll still get a
    NoMethodError because attr_reader wasn't called to create a method for it.

    --Ken

    --
    Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
    Department of Computer Science. Illinois Institute of Technology.
    http://www.iit.edu/~kbloom1/
    Ken Bloom, Sep 2, 2007
    #12
  13. 7stud 7stud

    Ken Bloom Guest

    On Sun, 02 Sep 2007 13:19:11 +0900, 7stud -- wrote:

    > Logan Capaldo wrote:
    >>Try this on for size:
    >>
    >> puts song.name
    >> puts song.instance_variables

    >
    > lol. I looked up instance_variables in "Programming Ruby (2d ed)" and it
    > says:
    >
    > "Note that simply defining an accessor does not create the corresponding
    > instance variables."
    >
    > That statement contradicts the statement I posted earlier on p. 31 of
    > the same book.


    For most purposes, you'll never notice the difference. There's only one
    where you will, and that's when you try to use the defined? keyword on it:

    class Foo
    def foo
    @foo=nil
    end
    def bar
    defined? @foo
    end
    end

    a=Foo.new => #<Foo:0xb7c58b9c>
    a.bar => nil
    a.foo => nil
    a.bar => "instance-variable"

    --Ken

    --
    Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
    Department of Computer Science. Illinois Institute of Technology.
    http://www.iit.edu/~kbloom1/
    Ken Bloom, Sep 4, 2007
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vivek
    Replies:
    3
    Views:
    106
    Patrick Hurley
    Dec 22, 2005
  2. Joe Ruby MUDCRAP-CE

    attr_reader + attr_writer?

    Joe Ruby MUDCRAP-CE, Oct 13, 2006, in forum: Ruby
    Replies:
    6
    Views:
    94
    Trans
    Oct 13, 2006
  3. Daniel Finnie

    attr_reader, etc for class variables

    Daniel Finnie, Dec 10, 2006, in forum: Ruby
    Replies:
    3
    Views:
    81
  4. libsfan01

    attr_reader explained

    libsfan01, Mar 3, 2007, in forum: Ruby
    Replies:
    5
    Views:
    93
    Eric Hodel
    Mar 5, 2007
  5. Hexren
    Replies:
    12
    Views:
    223
    Charles Calvert
    Apr 12, 2008
Loading...

Share This Page