Attr_reader vs Objects and Attributes

Hello World.
This is my first forum membership, and first post.
I am learning Ruby.
It seems to be a very elegant an encompassing OO language.
I'm reading Thomas & Hunt: Classes, Objects, and Variables on-line.

See attached.

Regarding the following by the authors, and attached I see no
correlation.
However I've had very good results with attr_accessor.
Please help.

class Song
  def name
    @name
  end
  def artist
    @artist
  end
  def duration
    @duration
  end
end
aSong = Song.new("Bicylops", "Fleck", 260)
aSong.artist » "Fleck"
aSong.name » "Bicylops"
aSong.duration » 260

···

------------------
class Song
  attr_reader :name, :artist, :duration
end
aSong = Song.new("Bicylops", "Fleck", 260)
aSong.artist » "Fleck"
aSong.name » "Bicylops"
aSong.duration » 260

Attachments:
http://www.ruby-forum.com/attachment/5878/TH_QA_1.doc
http://www.ruby-forum.com/attachment/5879/attr.rb

--
Posted via http://www.ruby-forum.com/.

Mike Onofrietto wrote in post #980715:

However I've had very good results with attr_accessor.
Please help.

You only defined reader methods. You also need:

  def name=(name)
    @name=name
  end
  def artist=(artist)
    @artist=artist
  end
  ... etc

'attr_accessor' gives you both reader and writer methods. 'attr_reader'
gives you just the reader ones (as in your code), and 'attr_writer'
gives just the writer ones.

In future, it would be very helpful if you could post the exact error
message you see. In your case it was probably something like
NoMethodError - unknown method 'artist=', which would have immediately
pinpointed the error.

Regards,

Brian.

···

--
Posted via http://www.ruby-forum.com/\.

Mike Onofrietto wrote in post #980715:

Hello World.
This is my first forum membership, and first post.
I am learning Ruby.
It seems to be a very elegant an encompassing OO language.
I'm reading Thomas & Hunt: Classes, Objects, and Variables on-line.

See attached.

Regarding the following by the authors, and attached I see no
correlation.
However I've had very good results with attr_accessor.
Please help.

In your test code, and the attachment, you don't have an initialize
function, which is defined in the first page of the book:

i.e.

class Song
  def initialize(name, artist, duration)
    @name = name
    @artist = artist
    @duration = duration
  end
end

The way Ruby works is that if this is defined, even if you have a new
class block i.e.

class Song
  def name; @name; end
  def artist; @artist; end
  def song; @song; end
end

that doesn't overwrite the previous definition. It EXTENDS it. So now
your class should be (in memory anyway) equivalent to:

class Song
  def initialize(name, artist, duration)
    @name = name
    @artist = artist
    @duration = duration
  end

  def name; @name; end
  def artist; @artist; end
  def song; @song; end
end

Without the initialization, you are called the base class
Object.new(*arr) method, which will not assigned any class variables for
you, regardless of whether you use attr_x methods or not.

Mac.

···

--
Posted via http://www.ruby-forum.com/\.

I believe he did not get an error message but an empty (nil) output
(other than he wrote):

Ruby version 1.9.2
irb(main):001:0> class Song; end
=> nil
irb(main):002:0> s = Song.new("Bicylops", "Fleck", 260)
=> #<Song:0x10195a40>
irb(main):003:0> s.instance_variables
=>

At least that would have been the case with the code he pasted.

Mike, your pasted code and output do not match. Also the code that
you referenced is not the one in the attachment. Please make sure you
report the real code and the real issue.

Cheers

robert

···

On Thu, Feb 10, 2011 at 9:33 AM, Brian Candler <b.candler@pobox.com> wrote:

Mike Onofrietto wrote in post #980715:

However I've had very good results with attr_accessor.
Please help.

You only defined reader methods. You also need:

def name=(name)
@name=name
end
def artist=(artist)
@artist=artist
end
... etc

'attr_accessor' gives you both reader and writer methods. 'attr_reader'
gives you just the reader ones (as in your code), and 'attr_writer'
gives just the writer ones.

In future, it would be very helpful if you could post the exact error
message you see. In your case it was probably something like
NoMethodError - unknown method 'artist=', which would have immediately
pinpointed the error.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Brian,
Thanks that helps.
The code I pasted was from the Thomas & Hunt manual, but maybe I took it
out of context.
Their presentation of the associated values further confused me.
aSong.artist » "Fleck"
aSong.name » "Bicylops"
aSong.duration » 260

Yes - I was thinking attr_accessor was some combination of
attr_reader, and attr_writer.
Thanks again, Mike

Brian Candler wrote in post #980745:

···

You only defined reader methods. You also need:

  def name=(name)
    @name=name
  end
  def artist=(artist)
    @artist=artist
  end
  ... etc

'attr_accessor' gives you both reader and writer methods. 'attr_reader'
gives you just the reader ones (as in your code), and 'attr_writer'
gives just the writer ones.

In future, it would be very helpful if you could post the exact error
message you see. In your case it was probably something like
NoMethodError - unknown method 'artist=', which would have immediately
pinpointed the error.

Regards,

Brian.

--
Posted via http://www.ruby-forum.com/\.

Paul,

Correct: they started that section with a fully initialized class, but
later wrote it as I pasted it.

Great example of extending the class, but I got the impression
that they redefined the to_s method.
Did they actually extend it too ?

Thanks for the thorough response, Mike

Paul Mckibbin wrote in post #980856:

···

Mike Onofrietto wrote in post #980715:

Hello World.
This is my first forum membership, and first post.
I am learning Ruby.
It seems to be a very elegant an encompassing OO language.
I'm reading Thomas & Hunt: Classes, Objects, and Variables on-line.

See attached.

Regarding the following by the authors, and attached I see no
correlation.
However I've had very good results with attr_accessor.
Please help.

In your test code, and the attachment, you don't have an initialize
function, which is defined in the first page of that section of the
book:

i.e.

class Song
  def initialize(name, artist, duration)
    @name = name
    @artist = artist
    @duration = duration
  end
end

The way Ruby works is that if this is defined, even if you have a new
class block i.e.

class Song
  def name; @name; end
  def artist; @artist; end
  def song; @song; end
end

that doesn't overwrite the previous definition. It EXTENDS it. So now
your class should be (in memory anyway) equivalent to:

class Song
  def initialize(name, artist, duration)
    @name = name
    @artist = artist
    @duration = duration
  end

  def name; @name; end
  def artist; @artist; end
  def song; @song; end
end

Without the initialization, you are calling the base class
Object.new(*arr) method, which will not assigned any class variables for
you, regardless of whether you use attr_x methods or not.

Mac.

--
Posted via http://www.ruby-forum.com/\.

Mac,

I got it.
Throughout the chapter the authors were merely extending the class from
case to case just as you described.

Take a look at my code. I extended the class twice:
1st: to implement attr_reader "long hand"
2nd: to implement attr_writer "long hand"

I still have question which will wait.

Thanks for your instruction, mikeonoff

Attachments:
http://www.ruby-forum.com/attachment/5908/extend_attr_longhand.rb

···

--
Posted via http://www.ruby-forum.com/.

Robert,

Thanks. The code, and output(?) I pasted, and attached are from the
Thomas, and Hunt manual. The other attachment was some similar test code
of mine.

The issue was my lack of understanding as to why they wrote the methods
without any initialization.

Thanks again, Mike

Robert Klemme wrote in post #980811:

···

On Thu, Feb 10, 2011 at 9:33 AM, Brian Candler <b.candler@pobox.com> > wrote:

@artist=artist
pinpointed the error.

I believe he did not get an error message but an empty (nil) output
(other than he wrote):

Ruby version 1.9.2
irb(main):001:0> class Song; end
=> nil
irb(main):002:0> s = Song.new("Bicylops", "Fleck", 260)
=> #<Song:0x10195a40>
irb(main):003:0> s.instance_variables
=>

At least that would have been the case with the code he pasted.

Mike, your pasted code and output do not match. Also the code that
you referenced is not the one in the attachment. Please make sure you
report the real code and the real issue.

Cheers

robert

--
Posted via http://www.ruby-forum.com/\.