attr_accessor question

Discussion in 'Ruby' started by Corey Konrad, Mar 17, 2007.

  1. Corey Konrad

    Corey Konrad Guest

    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

    --
    Posted via http://www.ruby-forum.com/.
    Corey Konrad, Mar 17, 2007
    #1
    1. Advertising

  2. On 3/17/07, Corey Konrad <> wrote:
    > how come this doesnt worh though?


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

    >
    > class Animal
    > attr_accessor :color
    > attr_accessor :size
    >
    > def initialize(color, size)
    > @color = color
    > @size = size
    > end
    > end
    >
    > 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:


    > 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
    >
    > --
    > 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/
    Rick DeNatale, Mar 17, 2007
    #2
    1. Advertising

  3. Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
    > 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


    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
    Stefano Crocco, Mar 17, 2007
    #3
  4. Corey Konrad

    Corey Konrad Guest

    Michael Guterl wrote:
    > On 3/17/07, Corey Konrad <> 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.

    --
    Posted via http://www.ruby-forum.com/.
    Corey Konrad, Mar 17, 2007
    #4
  5. Corey Konrad

    Corey Konrad Guest

    Michael Guterl wrote:
    > On 3/17/07, Corey Konrad <> 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}"




    --
    Posted via http://www.ruby-forum.com/.
    Corey Konrad, Mar 17, 2007
    #5
  6. Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
    > Michael Guterl wrote:
    > > On 3/17/07, Corey Konrad <> 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.


    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
    Stefano Crocco, Mar 17, 2007
    #6
  7. 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
    Stefano Crocco, Mar 17, 2007
    #7
  8. Corey Konrad

    Corey Konrad Guest


    >
    > 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

    --
    Posted via http://www.ruby-forum.com/.
    Corey Konrad, Mar 17, 2007
    #8
  9. Alle sabato 17 marzo 2007, Corey Konrad ha scritto:
    > > 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


    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
    Stefano Crocco, Mar 17, 2007
    #9
  10. Corey Konrad

    Corey Konrad Guest

    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



    --
    Posted via http://www.ruby-forum.com/.
    Corey Konrad, Mar 17, 2007
    #10
  11. On 3/17/07, Stefano Crocco <> wrote:

    > 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


    Actually the setter should be

    def var=(value)
    @var=value
    end

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
    Rick DeNatale, Mar 17, 2007
    #11
  12. Alle sabato 17 marzo 2007, Rick DeNatale ha scritto:
    > > def var=3Dvalue
    > > =A0@var=3Dvalue
    > > end

    >
    > Actually the setter should be
    >
    > =A0 =A0def var=3D(value)
    > =A0 =A0 =A0 @var=3Dvalue
    > =A0 =A0end


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

    Stefano
    Stefano Crocco, Mar 17, 2007
    #12
  13. 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.


    --
    NP: In Flames - As The Future Repeats Today
    Ist so, weil ist so
    Bleibt so, weil war so
    Sebastian Hungerecker, Mar 17, 2007
    #13
  14. On 3/17/07, Stefano Crocco <> wrote:
    > 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?


    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/
    Rick DeNatale, Mar 17, 2007
    #14
  15. Corey Konrad

    Gary Wright Guest

    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
    Gary Wright, Mar 17, 2007
    #15
  16. Hi --

    On 3/17/07, Stefano Crocco <> wrote:
    > 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?


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


    David

    --
    Q. What is THE Ruby book for Rails developers?
    A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
    Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
    A. Ruby Power and Light, LLC (http://www.rubypal.com)
    David A. Black, Mar 17, 2007
    #16
  17. Corey Konrad

    Phrogz Guest

    On Mar 17, 9:50 am, Corey Konrad <> wrote:
    > 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.


    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( :eek:range )
    => #<struct Animal color=:eek:range, 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>
    Phrogz, Mar 17, 2007
    #17
    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. Jim Cain
    Replies:
    0
    Views:
    92
    Jim Cain
    Jul 18, 2003
  2. David Garamond
    Replies:
    1
    Views:
    94
    Dan Doel
    Jan 25, 2004
  3. Jack, Paul
    Replies:
    2
    Views:
    105
    Robert Klemme
    Dec 16, 2004
  4. Tim Becker
    Replies:
    5
    Views:
    106
    Daniel Berger
    Nov 29, 2006
  5. Roland Swingler

    Question about attr_accessor

    Roland Swingler, Mar 3, 2007, in forum: Ruby
    Replies:
    5
    Views:
    104
    Roland Swingler
    Mar 3, 2007
Loading...

Share This Page