Forum: Ruby attr_accessor question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey Konrad (ckonrad)
on 2007-03-17 16:31
how come this doesnt worh though?

class Animal
  attr_accessor :color
  attr_accessor :size

  def initialize(color, size)
  @color = color
  @size = size
  end
end

animal = Animal.new
animal.color = "brown"
puts "The color of the animal is #{animal.color}"
animal.color = "red"
puts "Now the animal is #{animal.color}"
animal.size = "big"
puts "The size of the animal is #{animal.size}"



thanks
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2007-03-17 16:42
(Received via mailing list)
On 3/17/07, Corey Konrad <0011@hush.com> wrote:
> how come this doesnt worh though?

You don't say HOW it's not working.

>
> animal = Animal.new

I'm guessing that it's here, since you've defined initialize to
require two parameters and you aren't supplying any.

If that's the case try either

animal = Animal.new("purple", "teeny-weeny")

or make the arguments optional by providing defaults like:


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

def initialize(color='transparent', size='medium')
    @color = color
    @size = size
 end

or even

def initialize(color=nil, size=nil)
...

If you want to allow nil as an initial value.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-03-17 16:43
(Received via mailing list)
Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
> end
>
> thanks

Animal.new creates an instance of class Animal and calls its initialize
method, with the arguments you passed to new. Animal#initialize requires
two
arguments, so you must pass two arguments to Animal.new. For example:

animal=Animal.new "green", "little"

I hope this helps

Stefano
D337e2cf7c6d03caac6988d83e0e7f66?d=identicon&s=25 Michael Guterl (Guest)
on 2007-03-17 16:45
(Received via mailing list)
On 3/17/07, Corey Konrad <0011@hush.com> wrote:
>   end
> end
>
> animal = Animal.new


 ArgumentError: wrong number of arguments (0 for 2)

Your Animal.new is expecting you to pass in color and size.

animal = Animal.new("brown", "big")

animal.color = "brown"
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey Konrad (ckonrad)
on 2007-03-17 16:50
Michael Guterl wrote:
> On 3/17/07, Corey Konrad <0011@hush.com> wrote:
>>   end
>> end
>>
>> animal = Animal.new
>
>
>  ArgumentError: wrong number of arguments (0 for 2)
>
> Your Animal.new is expecting you to pass in color and size.
>
> animal = Animal.new("brown", "big")
>
> animal.color = "brown"


ah ok i understand that i am just learning all this OO stuff i just
thought i needed to use the initialize method but i dont even need to
create one for a default object state at all i can just do this as well
and the program worked fine,

class Animal
  attr_accessor :color
  attr_accessor :size
end

 that is pretty cool i'm having a fun time learning this language
compared to something like vb.net.
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey Konrad (ckonrad)
on 2007-03-17 17:13
Michael Guterl wrote:
> On 3/17/07, Corey Konrad <0011@hush.com> wrote:
>>   end
>> end
>>
>> animal = Animal.new
>
>
>  ArgumentError: wrong number of arguments (0 for 2)
>
> Your Animal.new is expecting you to pass in color and size.
>
> animal = Animal.new("brown", "big")
>
> animal.color = "brown"

now why when i add this new attribute attr_accessor :age i get the error
message
animal.rb:17 warning: parenthesize argument(s) for future versions
what does that error message mean? I tried putting parentheses around
the 25 but that didnt solve the problem i tried qoutes around the 25 how
do i use a number as an argument to an accessor?

class Animal
  attr_accessor :color
  attr_accessor :size
  attr_accessor :age
end

animal = Animal.new
animal.color = "brown"
puts "The color of the animal is #{animal.color}"
animal.color = "red"
puts "Now the animal is #{animal.color}"
animal.size = "big"
puts "The size of the animal is #{animal.size}"
animal.size = "small"
puts "Now the size of the animal is #{animal.size)"
animal.age = 25
puts "The age of the animal is #{animal.age}"
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-03-17 17:15
(Received via mailing list)
Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
> >
>   attr_accessor :color
>   attr_accessor :size
> end
>
>  that is pretty cool i'm having a fun time learning this language
> compared to something like vb.net.

Whenever you call the new method of a class, it calls the initialize
method of
the instance it just created. If you didn't define an initialize method
for
that class, the initialize method of the parent class will be called, or
the
parent class's parent... and so on. Going on the class hyerarchy, we
reach
Object#initialize, which (I think) does nothing.

If, as it often happens, you need instance variables, it's usually wise
to
define an initialize method in order to set them to a sensible value (or
to a
value passed by the caller using parameters). If you don't, the first
time
you reference an instance variable, it will be created and set to nil,
which
may not be what you want.

For example, take the following class

class C

 def greater? number
  @var > number
 end

end

As you can see, this class defines an instance method which tells
whether its
instance variable @var is greater than the given number or not.

Let's see what happens when we run this code:

c=C.new # Object#initialize is called.
c.instance_variables # No instance variables exist
=>[]
c.greater? 3

=>NoMethodError: undefined method `>' for nil:NilClass

We got an error, because @var is created on the spot and set to nil, and
nil
doesn't have a > method.

If we add an initialize method, instead, we have:

class C

 def initialize
  @var=0
 end

 def greater? number
  @var > number
 end

end

c=C.new #now, C#initialize is called
c.instance_variables
=> ["@var"] #now, @var exists
c.greater? 3
=> false
c.greater? -1
=> true

By the way, if you define an initialize method for a class which doesn't
derive directly from Object, you'll usually want to call the parent
class's
initialize from your own, otherwise the parent class's instance
variables
won't be initialized:

class A
 def initialize #We don't need to call Object#initialize: it does
nothing
  @var=0
 end
end

class B < A
 def initialize
  super #We call the parent class's initialize; otherwise, @var won't be
set
  @var1=1
 end
end

I hope this helps

Stefano
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-03-17 17:20
(Received via mailing list)
Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
> puts "Now the size of the animal is #{animal.size)"

You wrote ) instead of }. Aside from that, your code doesn't give me any
error.

By the way, you can declare more than one accessor at the time:

attr_accessor :color, :size, :age

Stefano
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey Konrad (ckonrad)
on 2007-03-17 17:23
>
> c=C.new #now, C#initialize is called
> c.instance_variables
> => ["@var"] #now, @var exists
> c.greater? 3
> => false
> c.greater? -1
> => true
>
> By the way, if you define an initialize method for a class which doesn't
> derive directly from Object, you'll usually want to call the parent
> class's
> initialize from your own, otherwise the parent class's instance
> variables
> won't be initialized:
>
> class A
>  def initialize #We don't need to call Object#initialize: it does
> nothing
>   @var=0
>  end
> end
>
> class B < A
>  def initialize
>   super #We call the parent class's initialize; otherwise, @var won't be
> set
>   @var1=1
>  end
> end
>
> I hope this helps
>
> Stefano

So i have to use the age accessor in an initialize method? i dont
understand what the difference is between the age accessor in that
example program and any of the others why would the age variable need to
be set before i used it and what does that have to do with the error
message i received telling me to parenthesize for future versions?

thanks
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-03-17 17:39
(Received via mailing list)
Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
> > class's
> >
> > Stefano
>
> So i have to use the age accessor in an initialize method? i dont
> understand what the difference is between the age accessor in that
> example program and any of the others why would the age variable need to
> be set before i used it and what does that have to do with the error
> message i received telling me to parenthesize for future versions?
>
> thanks

First the last question. Your last code contained a syntax error:

puts "Now the size of the animal is #{animal.size)"

The last character before the ending quote should be a }, not a ).


Regarding accessors and initialize: they're not related. The line

attr_accessor :var

is (more or less) simply a shortcut for this code:

def var
 @var
end

def var=value
 @var=value
end

In other words, attr_accessor is used to give access to instance
variables to
the world outside the instance itself. Initialize, on the other hand, is
often used to set the instance variables to sensible values. If you
don't set
them explicitly, they'll be created and set to nil the first time
they're
used. Usually, this is bad. For instance, if the variable will contain a
string, as in your example, sooner or later you'll want to call some
string
methods on it (such as sub or capitalize or downcase). If the instance
variable hasn't been created before, it will be created now and set to
nil,
then the method will be called on it. But since nil doesn't have those
methods, you'll get an error. Instead, if you set that variable to a
string
in initialize, you won't need to worry about that anymore.

To be simple: initialize is used to set the characteristics of an object
at
its birth. Accessors are used to change them later.

Stefano
139a2a2f6b330cc59a8dc6384bbf8837?d=identicon&s=25 Corey Konrad (ckonrad)
on 2007-03-17 17:43
Stefano Crocco wrote:
> Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
>> puts "Now the size of the animal is #{animal.size)"
>
> You wrote ) instead of }. Aside from that, your code doesn't give me any
> error.
>
> By the way, you can declare more than one accessor at the time:
>
> attr_accessor :color, :size, :age
>
> Stefano

ah ok man just a simple parentheses i hate when that happens,

attr_accessor :color, :size, :age

wow i can even make it shorter i love that

grazie mille
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2007-03-17 18:05
(Received via mailing list)
On 3/17/07, Stefano Crocco <stefano.crocco@alice.it> wrote:

> def var=value
>  @var=value
> end

Actually the setter should be

   def var=(value)
      @var=value
   end

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
C40020a47c6b625af6422b5b1302abaf?d=identicon&s=25 Stefano Crocco (crocco)
on 2007-03-17 19:11
(Received via mailing list)
Alle sabato 17 marzo 2007, Rick DeNatale ha scritto:
> > def var=value
> >  @var=value
> > end
>
> Actually the setter should be
>
>    def var=(value)
>       @var=value
>    end

Do you mean I should put value into brackets? If so, why? To me, it
seems that
my form works perfectly. Is there something I'm not aware of?

Stefano
7a561ec0875fcbbe3066ea8fe288ec77?d=identicon&s=25 Sebastian Hungerecker (Guest)
on 2007-03-17 20:23
(Received via mailing list)
Corey Konrad wrote:
> ah ok man just a simple parentheses i hate when that happens,

Some editors offer a feature where opening or closing parantheses,
brackets or
braces that don't have a corresponding closing or opening paranthesis,
bracket
or brace are highlighted in some way, so that this kind of mistake is
easily
spotted.
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2007-03-17 20:24
(Received via mailing list)
On 3/17/07, Stefano Crocco <stefano.crocco@alice.it> wrote:
>
> Do you mean I should put value into brackets? If so, why? To me, it seems that
> my form works perfectly. Is there something I'm not aware of?

I guess it's a matter of style.

The pickaxe gives the syntax of a method definition as:

  def defname [( [arg [ =val], ...] [, *vararg ] [ , &blockarg ] ) ]
       body
  end

Which implies that if arguments are present they must be enclosed in
parentheses.

I've always done so, and I can't recall having seen method
*definitions* which omitted the parens around the args.  But trying
this with both ruby1.8 and ruby1.9 I see that it neither complains
about the missing parens, something I didn't know until just now.

But I greatly prefer using the parens.  In fact my preference is to
use them for most method invocations as well, although omitting  them
there is more common.  I tend only to omit them in idiomatic cases
like

   attr_accessor :foo, :bar

instead of
   attr_accessor(:foo, :bar)

or when ruby is being used as a domain specific language.

I also notice that the pickaxe syntax is a little loose because it
won't admit valid things like

   def foo(&block)
      ...
   end

So it's really a pedagogical syntax.


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 Gary Wright (Guest)
on 2007-03-17 21:54
(Received via mailing list)
On Mar 17, 2007, at 3:23 PM, Rick DeNatale wrote:
> I've always done so, and I can't recall having seen method
> *definitions* which omitted the parens around the args.

You know how the coding style found in "The C Programming Language"
by Kernighhan and Ritchie is always referenced as K&R style?

Whenever I see Ruby methods defined without parens around the
formal arguments I call it the Ara style in my head.  I see other
people use that style but Ara seems to be the most visible member
of the community with that predilection.

Gary Wright
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 David A. Black (Guest)
on 2007-03-17 21:58
(Received via mailing list)
Hi --

On 3/17/07, Stefano Crocco <stefano.crocco@alice.it> wrote:
>
> Do you mean I should put value into brackets? If so, why? To me, it seems that
> my form works perfectly. Is there something I'm not aware of?

It looks a bit unusual, not having parentheses or at least a space.
But it will parse.


David
852a62a28f1de229dc861ce903b07a60?d=identicon&s=25 Gavin Kistner (phrogz)
on 2007-03-18 00:16
(Received via mailing list)
On Mar 17, 9:50 am, Corey Konrad <0...@hush.com> wrote:
>  that is pretty cool i'm having a fun time learning this language
> compared to something like vb.net.

Ruby also has a nice class named Struct for easily creating classes
(or starting them off) that are just piles of optional attributes by
name:

[sliver:~] gkistner$ irb
irb(main):001:0> Animal = Struct.new( :color, :size )
=> Animal
irb(main):002:0> a1 = Animal.new
=> #<struct Animal color=nil, size=nil>
irb(main):003:0> a1.color
=> nil
irb(main):004:0> a1.color = :blue
=> :blue
irb(main):005:0> a1
=> #<struct Animal color=:blue, size=nil>
irb(main):006:0> a2 = Animal.new( :orange )
=> #<struct Animal color=:orange, size=nil>
irb(main):007:0> a3 = Animal.new( :red, 42 )
=> #<struct Animal color=:red, size=42>
irb(main):008:0> a3.size = 50
=> 50
irb(main):009:0> a3
=> #<struct Animal color=:red, size=50>
This topic is locked and can not be replied to.