Ruby beginner question 2

(Alucard) #1

Hi all!

I'm using ruby 1.82. This is the code copy from www.ruby-lang.org,
programming ruby.

And I found that both the following code cannot run, with the following
error occur:

song_2.rbw:4:in `initialize': wrong number of arguments (3 for 0)
(ArgumentError)
  from song_2.rbw:4:in `new'
  from song_2.rbw:4

So, what is going wrong?

Thanks in advance!

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

···

#--------------------------------------------------------------------------------------------

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

(Jeff Wood) #2

Alucard wrote:

Hi all!

I'm using ruby 1.82. This is the code copy from www.ruby-lang.org,
programming ruby.

And I found that both the following code cannot run, with the following
error occur:

song_2.rbw:4:in `initialize': wrong number of arguments (3 for 0)
(ArgumentError)
from song_2.rbw:4:in `new'
from song_2.rbw:4

So, what is going wrong?

Thanks in advance!

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

#--------------------------------------------------------------------------------------------

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

Your objects have no constructor method ... therefore, it's simply
relying on the constructor from Object ( which is implicitly inherited ).

So, simply add

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

within either of your class definition examples... then they'll work.

The inherited constructor from Object takes no parameters, and that's
why you are getting the "initialize wrong number of arguments 3 for
0"... You're passing 3 to a no argument constructor...

Hope that helps.

j.

(Robert) #3

Jeff Wood wrote:

···

Alucard wrote:

Hi all!

I'm using ruby 1.82. This is the code copy from www.ruby-lang.org,
programming ruby.

And I found that both the following code cannot run, with the
following error occur:

song_2.rbw:4:in `initialize': wrong number of arguments (3 for 0)
(ArgumentError)
from song_2.rbw:4:in `new'
from song_2.rbw:4

So, what is going wrong?

Thanks in advance!

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

#-------------------------------------------------------------------------
-------------------

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

Your objects have no constructor method ... therefore, it's simply
relying on the constructor from Object ( which is implicitly
inherited ).

So, simply add

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

within either of your class definition examples... then they'll work.

The inherited constructor from Object takes no parameters, and that's
why you are getting the "initialize wrong number of arguments 3 for
0"... You're passing 3 to a no argument constructor...

A simpler alternative is to just use Struct:

# direct
Song = Struct.new :name, :artist, :duration

class Song
  # other methods
end

Kind regards

    robert

(Jacek) #4

Robert Klemme napisał(a):

Jeff Wood wrote:

Alucard wrote:

Hi all!

I'm using ruby 1.82. This is the code copy from www.ruby-lang.org,
programming ruby.

And I found that both the following code cannot run, with the
following error occur:

song_2.rbw:4:in `initialize': wrong number of arguments (3 for 0)
(ArgumentError)
from song_2.rbw:4:in `new'
from song_2.rbw:4

So, what is going wrong?

Thanks in advance!

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

#-------------------------------------------------------------------------
-------------------

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

Your objects have no constructor method ... therefore, it's simply
relying on the constructor from Object ( which is implicitly
inherited ).

So, simply add

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

within either of your class definition examples... then they'll work.

The inherited constructor from Object takes no parameters, and that's
why you are getting the "initialize wrong number of arguments 3 for
0"... You're passing 3 to a no argument constructor...

A simpler alternative is to just use Struct:

# direct
Song = Struct.new :name, :artist, :duration

class Song
  # other methods
end

Kind regards

    robert

Sometimes, during the proces of teaching it is not a good idea
to give and alternative :slight_smile:

Jacek

(Gavin Kistner) #5

A simpler alternative is to just use Struct:

# direct
Song = Struct.new :name, :artist, :duration

class Song
  # other methods
end

Wait wait wait...I never grokked Struct before.

Is it really just a convenient factory for generating classes with a set of accessor properties, and a constructor that accepts zero or more of those properties in order?

Holy crap, I see that Song.class is in fact Class.

I may finally get it! Re-reading the ri documentation for Struct, I see that the above is sort of what it's trying to say. But the wording always made me believe that the returned object was some sort of non-class class. Some half-breed freakiness.

The combination of the name and documentation threw me off before. I suppose 'Struct' sort of works, but something like 'AttributeClass' (while wordier and not as memorable). So apparently I have no better suggestion for the name. But for the documentation...

At a minimum, I suggest replacing the first sentence:
"A +Struct+ is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class."

Maybe I'm the only one (am I the only one?) but that makes it sound like the return value isn't a class. Instead, I suggest something like:

The +Struct+ class provides a convenient way to quickly create a class that contains a set of attributes. In addition to predefining the accessor methods for these attributes, the returned class contains other instance methods for accessing and modifying the attributes. (These methods are documented below as instance methods of the Struct class, but are in fact methods available to instances of the class returned from the call to Struct.new).

For example:
   User = Struct.new( :first, :last, :email )
   p User.class #=> Class
   p User.superclass #=> Struct

   nobody = User.new
   gk = User.new( 'Gavin', 'Kistner' )
   p nobody #=> #<struct User first=nil, last=nil, email=nil>
   p gk #=> #<struct User first="Gavin", last="Kistner", email=nil>
   p gk.size #=> 3
   gk.email = 'gavin@refinery.com'

   p gk.members #=> ["first", "last", "email"]
   p gk.values #=> ["Gavin", "Kistner", "gavin@refinery.com"]
   p gk.values_at(1..2) #=> ["Kistner", "gavin@refinery.com"]
   p gk.first #=> "Gavin"
   p gk['last'] #=> "Kistner"

   class User
     def fullname
       "#{first} #{last}"
     end
   end

   p gk.fullname #=> "Gavin Kistner"

(I think it's very helpful to have an example usage at the very top of the documentation, showing a simple usage with a type of object that everyone understands. Obviously, it doesn't have to be my name or email, though :wink:

Also, the documentation for the Struct#values_at method seems to have been lifted from the Array#values_at method, without changing the example code to use a Struct rather than array. The example should be something like:

Stuff = Struct.new( :a, :b, :c, :d, :e, :f )
chars = Stuff.new( 'a1', 'b1', 'c1', 'd1', 'e1', 'f1' )
p chars.values_at(1, 3, 5) #=> ["b1", "d1", "f1"]
p chars.values_at(-1, -3, -5) #=> ["f1", "d1", "b1"]
p chars.values_at(1..3, 2...5) #=> ["b1", "c1", "d1", "c1", "d1", "e1"]
p chars.values_at(1,7) #=> offset 7 too large for struct(size:6) (IndexError)

(Aside: Has anyone ever used the #values_at method of the Struct class? If so, what for?)

···

On Aug 22, 2005, at 2:31 AM, Robert Klemme wrote:

cc: ruby-doc mailing list

(Chris Game) #6

balcer wrote:

Sometimes, during the proces of teaching it is not a good idea
to give and alternative :slight_smile:

Especially as the OP was on p30 of the book, and 'Struct' hasn't
come up yet!

···

--
Chris Game

"During my service in the United States Congress, I took the
initiative in creating the Internet." - Al Gore, March 9, 1999

(Gavin Kistner) #7

(These methods are documented below as instance methods of the Struct class, but are in fact methods available to instances of the class returned from the call to Struct.new)

That one sentence should probably read something like:

···

On Aug 22, 2005, at 6:37 AM, Gavin Kistner wrote:

(These methods, such as #values, are documented below as instance methods of the Struct class; as the returned class inherits from Struct, they are available instances of the class returned from the call to Struct.new.)

(BearItAll) #8

Yes, it's just you that missed that one.

Sorry, put the handkerchief away, I was fibbing, I didn't really get that
part either. In fact I believe they is a hidden bible of Ruby somewhere
that all these other users have copies of but we poor souls are left to
struggle. Perhaps they all worship at the feet of The Great Rudy
Blubber oops I mean Great Ruby Buddha (sorry, it's my accent), so are
rewarded with nice things such as snippets of code with explanations in
it.

But I'm darn well determined, I am certain that Ruby-rails is a good thing
so certain that although I can't get anything at all in ruby-rails to
work at the moment, I'm going to keep trying.

···

On Mon, 22 Aug 2005 21:37:43 +0900, Gavin Kistner wrote:

On Aug 22, 2005, at 2:31 AM, Robert Klemme wrote:

A simpler alternative is to just use Struct:

# direct
Song = Struct.new :name, :artist, :duration

class Song
  # other methods
end

Wait wait wait...I never grokked Struct before.

Is it really just a convenient factory for generating classes with a
set of accessor properties, and a constructor that accepts zero or
more of those properties in order?

Holy crap, I see that Song.class is in fact Class.

I may finally get it! Re-reading the ri documentation for Struct, I
see that the above is sort of what it's trying to say. But the
wording always made me believe that the returned object was some sort
of non-class class. Some half-breed freakiness.

The combination of the name and documentation threw me off before. I
suppose 'Struct' sort of works, but something like
'AttributeClass' (while wordier and not as memorable). So apparently
I have no better suggestion for the name. But for the documentation...

At a minimum, I suggest replacing the first sentence:
"A +Struct+ is a convenient way to bundle a number of attributes
together, using accessor methods, without having to write an explicit
class."

Maybe I'm the only one (am I the only one?) but that makes it sound
like the return value isn't a class. Instead, I suggest something like:

(Robert) #9

Gavin Kistner wrote:

A simpler alternative is to just use Struct:

# direct
Song = Struct.new :name, :artist, :duration

class Song
  # other methods
end

Wait wait wait...I never grokked Struct before.

Is it really just a convenient factory for generating classes with a
set of accessor properties, and a constructor that accepts zero or
more of those properties in order?

Holy crap, I see that Song.class is in fact Class.

I may finally get it! Re-reading the ri documentation for Struct, I
see that the above is sort of what it's trying to say. But the
wording always made me believe that the returned object was some sort
of non-class class. Some half-breed freakiness.

The combination of the name and documentation threw me off before. I
suppose 'Struct' sort of works, but something like
'AttributeClass' (while wordier and not as memorable). So apparently
I have no better suggestion for the name. But for the documentation...

At a minimum, I suggest replacing the first sentence:
"A +Struct+ is a convenient way to bundle a number of attributes
together, using accessor methods, without having to write an explicit
class."

Maybe I'm the only one (am I the only one?) but that makes it sound
like the return value isn't a class. Instead, I suggest something
like:

The +Struct+ class provides a convenient way to quickly create a
class that contains a set of attributes. In addition to predefining
the accessor methods for these attributes, the returned class
contains other instance methods for accessing and modifying the
attributes. (These methods are documented below as instance methods
of the Struct class, but are in fact methods available to instances
of the class returned from the call to Struct.new).

For example:
   User = Struct.new( :first, :last, :email )
   p User.class #=> Class
   p User.superclass #=> Struct

   nobody = User.new
   gk = User.new( 'Gavin', 'Kistner' )
   p nobody #=> #<struct User first=nil, last=nil, email=nil>
   p gk #=> #<struct User first="Gavin", last="Kistner",
email=nil>
   p gk.size #=> 3
   gk.email = 'gavin@refinery.com'

   p gk.members #=> ["first", "last", "email"]
   p gk.values #=> ["Gavin", "Kistner", "gavin@refinery.com"]
   p gk.values_at(1..2) #=> ["Kistner", "gavin@refinery.com"]
   p gk.first #=> "Gavin"
   p gk['last'] #=> "Kistner"

   class User
     def fullname
       "#{first} #{last}"
     end
   end

   p gk.fullname #=> "Gavin Kistner"

(I think it's very helpful to have an example usage at the very top
of the documentation, showing a simple usage with a type of object
that everyone understands. Obviously, it doesn't have to be my name
or email, though :wink:

+10 for the doc addenum - I went through the same some time ago. It took
me smoe experimenting to full grasp the power and beauty of Struct.

Also, I found the option to name the struct by providing a first parameter
quite irritating. I haven't found any uses for this yet.

st = Struct.new "Xxx", :name

=> Struct::Xxx

Struct::Xxx

=> Struct::Xxx

Struct::Xxx.new "rr"

=> #<struct Struct::Xxx name="rr">

Also, the documentation for the Struct#values_at method seems to have
been lifted from the Array#values_at method, without changing the
example code to use a Struct rather than array. The example should be
something like:

Stuff = Struct.new( :a, :b, :c, :d, :e, :f )
chars = Stuff.new( 'a1', 'b1', 'c1', 'd1', 'e1', 'f1' )
p chars.values_at(1, 3, 5) #=> ["b1", "d1", "f1"]
p chars.values_at(-1, -3, -5) #=> ["f1", "d1", "b1"]
p chars.values_at(1..3, 2...5) #=> ["b1", "c1", "d1", "c1", "d1",
"e1"] p chars.values_at(1,7) #=> offset 7 too large for
struct(size:6) (IndexError)

(Aside: Has anyone ever used the #values_at method of the Struct
class? If so, what for?)

I never used it but it makes Struct a bit more compatible to Array. Note
also:

Foo = Struct.new :name, :val

=> Foo

f=Foo.new "n", "v"

=> #<struct Foo name="n", val="v">

f[0]

=> "n"

f[1]

=> "v"

f.each {|x| p x}

"n"
"v"
=> #<struct Foo name="n", val="v">

f.each_ {|x| p x}

f.each_pair f.each_with_index

f.each_pair {|a,b| print a,"=>",b,"\n"}

name=>n
val=>v
=> #<struct Foo name="n", val="v">>> Foo.ancestors
=> [Foo, Struct, Enumerable, Object, Kernel]

IOW, classes created by Struct.new are Enumerable and support an Array
like interface. :slight_smile:

Kind regards

    robert

···

On Aug 22, 2005, at 2:31 AM, Robert Klemme wrote:

(Randy Kramer) #10

As a newbie / learner (but not the original OP), I am happy to have the
alternative presented, especially if it is simpler or better in some way
(maybe even better for teaching, but generally worse in other ways). I may
be overwhelmed, but I have the choice to pay attention to the alternative or
not.

Randy Kramer

PS: Just to complain, you had to quote all that other text to make your
comment?

···

On Monday 22 August 2005 06:01 am, balcer wrote:

Sometimes, during the proces of teaching it is not a good idea
to give and alternative :slight_smile:

(Robert) #11

BearItAll wrote:

<snip/>

Maybe I'm the only one (am I the only one?) but that makes it sound
like the return value isn't a class. Instead, I suggest something
like:

Yes, it's just you that missed that one.

:-)))

Sorry, put the handkerchief away, I was fibbing, I didn't really get
that part either. In fact I believe they is a hidden bible of Ruby
somewhere that all these other users have copies of but we poor souls
are left to struggle. Perhaps they all worship at the feet of The
Great Rudy
Blubber oops I mean Great Ruby Buddha (sorry, it's my accent), so are
rewarded with nice things such as snippets of code with explanations
in it.

Erm... Ruby Buddha is in fact just an alias for ruby-talk. :slight_smile: That's
how *I* got to know Struct anyway.

But I'm darn well determined, I am certain that Ruby-rails is a good
thing so certain that although I can't get anything at all in
ruby-rails to work at the moment, I'm going to keep trying.

That's the spirit!

Kind regards

    robert

···

On Mon, 22 Aug 2005 21:37:43 +0900, Gavin Kistner wrote:

(Gaston Garcia) #12

I would say, to not use the alternative right now. I think the guys in the
book lead us through a buch of steps for a reason.

···

On 8/22/05, Randy Kramer <rhkramer@gmail.com> wrote:

On Monday 22 August 2005 06:01 am, balcer wrote:
> Sometimes, during the proces of teaching it is not a good idea
> to give and alternative :slight_smile:

As a newbie / learner (but not the original OP), I am happy to have the
alternative presented, especially if it is simpler or better in some way
(maybe even better for teaching, but generally worse in other ways). I may
be overwhelmed, but I have the choice to pay attention to the alternative
or
not.

Randy Kramer

PS: Just to complain, you had to quote all that other text to make your
comment?

--
-gaston

(Chris Game) #13

Gaston Garcia wrote:

I would say, to not use the alternative right now. I think the
guys in the book lead us through a buch of steps for a reason.

That being said the book could do with proper editing. As it is
several concepts are used without proper explanation (binding,
scope, precedence,...)

···

--
Chris Game

"A witty saying proves nothing." -- Voltaire