Multiple Initialize methods?

Hi,

I need to create a class either with a param in the construction or nothing:

something = Object.new

or

something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two params. If
I try to create the object with nothing (first version) then I get
"ArgumentError: wrong number of arguments(0 for 2)".

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i needed at
least a marker.

Thanks for any help,

Nick.

ruby does not support method overloading - you may only a single method
signature for a give name. you can do something like:

~ > cat foo
class Klass
def initialize(*args)
args.size == 0 ?
init0() :
init1(*args[0…1])
end
private
def init0
@x = 4
@y = 2
end
def init1 x, y
@x = x
@y = y
end
def inspect; @x.to_s << @y.to_s; end
end

k = Klass.new
p k
k = Klass.new 4, 2
p k

class Klass
def initialize args = {}
@x = args[:x] || 4
@y = args[:y] || 2
end
end

k = Klass.new
p k
k = Klass.new :x => 4, :y => 2
p k

~ > ruby foo
42
42
42
42

-a

···

On Wed, 11 Jun 2003, Nick wrote:

Hi,

I need to create a class either with a param in the construction or nothing:

something = Object.new

or

something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two params. If
I try to create the object with nothing (first version) then I get
“ArgumentError: wrong number of arguments(0 for 2)”.

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i needed at
least a marker.

Thanks for any help,

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ara.t.howard@noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
~ > ruby -e ‘p(%.\x2d\x29…intern)’
====================================

You can’t overload initialize like that in ruby.

Could you do something like

def initialize(*args) which would give you an array or args of size
args.size

or

def.initialize(val1=nil,val2=nil) with obvious results

Andrew

Nick wrote:

···

Hi,

I need to create a class either with a param in the construction or nothing:

something = Object.new

or

something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two params. If
I try to create the object with nothing (first version) then I get
“ArgumentError: wrong number of arguments(0 for 2)”.

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i needed at
least a marker.

Thanks for any help,

Nick.

Set the parameters to some default value that will let you know if they were
passed:

class Whatever
NOT_GIVEN = -1
def initialize(xdim = NOT_GIVEN, ydim = NOT_GIVEN)
if xdim = NOT_GIVEN
xdim = foo
etc.

w = Whatever.new
w = Whatever.new(23, 44)

Regards,
JJ

···

on 6/11/03 3:54 PM, Nick at nick.robinson@f.co.uk wrote:

Hi,

I need to create a class either with a param in the construction or nothing:

something = Object.new

or

something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two params. If
I try to create the object with nothing (first version) then I get
“ArgumentError: wrong number of arguments(0 for 2)”.

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i needed at
least a marker.

Thanks for any help,

Nick.

Ruby isn’t C++; there is no overloading in that way. What you want
is perhaps:

class Something
def initialize(xdim = nil, ydim = nil)
@xdim = xdim || 0
@ydim = ydim || 0
end
end

You can also use *args.

-austin

···

On Thu, 12 Jun 2003 04:54:59 +0900, Nick wrote:

Hi,

I need to create a class either with a param in the construction
or nothing:

something = Object.new
or
something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two
params. If I try to create the object with nothing (first version)
then I get “ArgumentError: wrong number of arguments(0 for 2)”.

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i
needed at least a marker.


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.06.11
* 16:32:43

Do it like this:

class Something
def initialize(xdim=defaultval, ydim=defaultvalue)
# do stuff. When xdim or ydim are not given, they will be set to
“defaultvalue”
end
end

Or, you could gather the args up in an array:

class Something
def initialize(*args)
# Do stuff. args is an array with all arguments given to the method
end
end

Jason Creighton

···

On Wed, 11 Jun 2003 19:36:18 +0000 (UTC) “Nick” nick.robinson@f.co.uk wrote:

Hi,

I need to create a class either with a param in the construction or nothing:

something = Object.new

or

something = Object.new(val1, val2)

see http://www.rubygarden.org/ruby?RubyFromCpp

robert

“Nick” nick.robinson@f.co.uk schrieb im Newsbeitrag
news:bc80bi$jp8$1@hercules.btinternet.com

Hi,

I need to create a class either with a param in the construction or
nothing:

something = Object.new

or

something = Object.new(val1, val2)

I have created an emtpy initialize() method and one with the two params.
If
I try to create the object with nothing (first version) then I get
“ArgumentError: wrong number of arguments(0 for 2)”.

class Something
def initialize()
end
def initialize(xdim, ydim)
@xdim = xdim
@ydim = ydim
end

I put the empty initialze in when things didnt work, thinking i needed
at

···

least a marker.

Thanks for any help,

Nick.

It occurs to me that a standard way to do something like this in Ruby
is as follows (taken from set.rb):

The code below gives two methods to create the object:

Set.new [returns empty set]

Set.new([array]) [returns a set, each element of which is an element
of the given array (without duplicates)]

Set.new({hash}) [returns a set, each element of which is an array
consisting of the given key-value pairs]

Set[array] [returns a set, each element of which is an element of the
given array (without duplicates)]

Set. [returns a set, each element of which is one of the
given elements (without duplicates)]

Code from set.rb:

Creates a new set containing the given objects. [Notice the call to

the ‘new’ method.]
def self.
new(ary)
end

Creates a new set containing the elements of the given enumerable

object.

···

On Thu, 12 Jun 2003 04:54:59 +0900, Nick wrote:

Hi,

I need to create a class either with a param in the construction
or nothing:

something = Object.new
or
something = Object.new(val1, val2)

[snip]

If a block is given, the elements of enum are preprocessed by the

given block.

def initialize(enum = nil, &block) # :yields: o
@hash ||= Hash.new

 enum.nil? and return

 if block
   enum.each { |o| add(block[o]) }
 else
   merge(enum)
 end

end

Hi everybody,

Thanks for the replies. I appreciate Ruby isnt C++, or C# or Delphi, or …
but typically you can have more than one constructor in those languages -
because typically people have requested the functionality from the language
because they help. I think I will reluctantly go with the setting default
values for the params. Its not nice in my view, but it will do.

Thanks to everyone who replied…much appreciated.

Nick.
“Jason Creighton” androflux@remove.to.reply.softhome.net wrote in message
news:20030611174214.678930cc.androflux@remove.to.reply.softhome.net

Hi,

I need to create a class either with a param in the construction or
nothing:

···

On Wed, 11 Jun 2003 19:36:18 +0000 (UTC) > “Nick” nick.robinson@f.co.uk wrote:

something = Object.new

or

something = Object.new(val1, val2)

Do it like this:

class Something
def initialize(xdim=defaultval, ydim=defaultvalue)
# do stuff. When xdim or ydim are not given, they will be set to
“defaultvalue”
end
end

Or, you could gather the args up in an array:

class Something
def initialize(*args)
# Do stuff. args is an array with all arguments given to the method
end
end

Jason Creighton

Set the parameters to some default value that will let you know if they were
passed:

class Whatever
NOT_GIVEN = -1
def initialize(xdim = NOT_GIVEN, ydim = NOT_GIVEN)
if xdim = NOT_GIVEN

I think you mean ==

        xdim = foo

etc.

Regards,

Brian.

···

On Thu, Jun 12, 2003 at 05:21:20AM +0900, John Johnson wrote:

Nick,

A common idiom in type-less languages like Ruby, Smalltalk and others is
that you see class methods that take the parameters specific to that usage.
They then turn around and call an internal method that does the actual
construction and then return the result. Much like the Factory pattern.
This makes sense as each class really is a factory for instances. It also
makes sense to name creation methods for what they are doing instead of just
‘new’ with another parameter! In C++ your constructor does both your
instance creation and initialization. In Ruby specifically, those tasks are
separate. But even with that, one of the ideas of OOP is to have your
problem use the domain language. That should include creating new objects
you need. I need a new Point or a new Point with X or a new Point with X
and Y. So making the creation methods read that way is not such a bad idea.

So we may have these methods (based on your example below)
Point.zero
Point.withX(var1)
Point.withX_withY(var1, var2)

Each of these in turn is implemented something like so:

def Point.zero
return self.new()

#Could also do this as well - chaining variant of the idea
#return Point.withX(0)

end

def Point.withX(var1)
return self.new(var1)

#Could also do this as well - chaining variant of the idea
#return Point.withX_withY(var1, 0)

end

def Point.withX_withY(var1, var2)
return self.new(var1, var2)
end

def initialize(var1 = 0, var2 = 0)
@x = var1
@y = var2
end

This has these positive properties:

  1. Method names that mean something in the domain language.
  2. Gives class method creation methods that are clearly spelled out. Not
    just another variant of new with another parameter
  3. Allows the class methods to override the default values if for there case
    they want it to be different than what initialize specifics and they are not
    given a value for an argument
  4. If you use the chaining variant it allows you to work from the most
    general usage (no args) to the most specific (all args) and have each
    creation method do what it needs to do then pass on the task of creation.
    And in Ruby, by the time you get to initialize, lots of error checking on
    the args could have already been done, etc. So that initializations need to
    do that is minimal.

Hope this idea helps…

···


Sam Griffith Jr.
email: staypufd@mac.com
Web site: http://homepage.mac.com/staypufd/index.html

On 6/12/2003 12:11 AM, in article bc921m$nmg$1@titan.btinternet.com, “Nick” nick.robinson@f.co.uk wrote:

Hi everybody,

Thanks for the replies. I appreciate Ruby isnt C++, or C# or Delphi, or …
but typically you can have more than one constructor in those languages -
because typically people have requested the functionality from the language
because they help. I think I will reluctantly go with the setting default
values for the params. Its not nice in my view, but it will do.

Thanks to everyone who replied…much appreciated.

Nick.
“Jason Creighton” androflux@remove.to.reply.softhome.net wrote in message
news:20030611174214.678930cc.androflux@remove.to.reply.softhome.net

On Wed, 11 Jun 2003 19:36:18 +0000 (UTC) >> “Nick” nick.robinson@f.co.uk wrote:

Hi,

I need to create a class either with a param in the construction or
nothing:

something = Object.new

or

something = Object.new(val1, val2)

Do it like this:

class Something
def initialize(xdim=defaultval, ydim=defaultvalue)
# do stuff. When xdim or ydim are not given, they will be set to
“defaultvalue”
end
end

Or, you could gather the args up in an array:

class Something
def initialize(*args)
# Do stuff. args is an array with all arguments given to the method
end
end

Jason Creighton

Nick wrote:

Hi everybody,

Thanks for the replies. I appreciate Ruby isnt C++, or C# or Delphi, or …
but typically you can have more than one constructor in those languages -
because typically people have requested the functionality from the language
because they help. I think I will reluctantly go with the setting default
values for the params. Its not nice in my view, but it will do.

I haven’t followed this thread, but has anyone suggested construction
methods (sometimes called factory methods?). Make the constructor
private, and use class methods to construct specific objects:

class Square
def Square.with_area(area)
new(Math.sqrt(area))
end

  def Square.with_diagonal(diag)
      new(diag/Math.sqrt(2))
  end

  def Square.with_side(side)
      new(side)
  end

  private_class_method :new

  def initialize(side)
    @side = side
  end

end

s1 = Square.with_area(4)
s2 = Square.with_diagonal(2.828427)
s3 = Square.with_side(2)

The joy of this approach is that not everything has to be done in the
constructor: because no one else can call it, the constructor can create
a partially initialized object, leaving it up to your construction
methods to complete the job.

Cheers

Dave

Nick,

A common idiom in type-less languages like Ruby, Smalltalk and others is

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.

that you see class methods that take the parameters specific to that usage.
They then turn around and call an internal method that does the actual
construction and then return the result. Much like the Factory pattern.
[…]
And in Ruby, by the time you get to initialize, lots of error checking on
the args could have already been done, etc. So that initializations need to
do that is minimal.

This should all go into the Wiki :slight_smile:

···

On Thu, Jun 19, 2003 at 05:40:02PM +0900, Sam Griffith wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Q: What’s the big deal about rm, I have been deleting stuff for years? And
never lost anything… oops!
A: …
– From the Frequently Unasked Questions

I thought I had suggested something like this in my earlier message
citing how set.rb defines a second constructor ( ‘’ ) that
references the initialize method. Your suggested approach, however,
seems better and clearer.

Should approaches like this (and others that come to be accepted as
best practices) be used in all “official” parts of Ruby that are
written in Ruby?

···

On Thursday, June 12, 2003, at 01:29 AM, Dave Thomas wrote:

[snip]

I haven’t followed this thread, but has anyone suggested construction
methods (sometimes called factory methods?). Make the constructor
private, and use class methods to construct specific objects:

[snip examples]

Objects aren’t type-less, but variables are. But I should have been more
clear. Sorry about that!

Thx,

···

On 6/19/2003 3:46 AM, in article 20030619084602.GA8628@student.ei.uni-stuttgart.de, “Mauricio Fernández” batsman.geo@yahoo.com wrote:

On Thu, Jun 19, 2003 at 05:40:02PM +0900, Sam Griffith wrote:

Nick,

A common idiom in type-less languages like Ruby, Smalltalk and others is

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.


Sam Griffith Jr.
email: staypufd@mac.com
Web site: http://homepage.mac.com/staypufd/index.html

There’s already for instance File.new and File.open.

···

On Thu, Jun 12, 2003 at 02:54:14PM +0900, Mark Wilson wrote:

I thought I had suggested something like this in my earlier message
citing how set.rb defines a second constructor ( ‘’ ) that
references the initialize method. Your suggested approach, however,
seems better and clearer.

Should approaches like this (and others that come to be accepted as
best practices) be used in all “official” parts of Ruby that are
written in Ruby?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

No, that’s wrong too. Now there’s a race condition between the rm and
the mv. Hmm, I need more coffee.
– Guy Maor on Debian Bug#25228

Sorry for being so nit-picking.

I still think your post would be a nice addition to the Wiki (hint, hint :slight_smile:

···

On Thu, Jun 19, 2003 at 09:43:19PM +0900, Sam Griffith wrote:

On 6/19/2003 3:46 AM, in article > 20030619084602.GA8628@student.ei.uni-stuttgart.de, “Mauricio Fernández” > batsman.geo@yahoo.com wrote:

On Thu, Jun 19, 2003 at 05:40:02PM +0900, Sam Griffith wrote:

Nick,

A common idiom in type-less languages like Ruby, Smalltalk and others is

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.

Objects aren’t type-less, but variables are. But I should have been more
clear. Sorry about that!


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

We come to bury DOS, not to praise it.
– Paul Vojta, vojta@math.berkeley.edu

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.

Not to nit-pick here, but in perl aren’t “1” and 1 the same type
(“scalar”) but different contexts?

Or is that just a semantic nit?

···

Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!

Don’t know much about Perl, but isn’t “scalar” a context (the other
one being list)?

···

On Thu, Jun 19, 2003 at 11:42:55PM +0900, Michael Campbell wrote:

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.

Not to nit-pick here, but in perl aren’t “1” and 1 the same type
(“scalar”) but different contexts?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Whoa…I did a ‘zcat /vmlinuz > /dev/audio’ and I think I heard God…
– mikecd on #Linux

In article 20030619144253.10746.qmail@web12404.mail.yahoo.com,

They are not type-less there are dynamically typed.
Doing
a = 1 + “1”
doesn’t work in Ruby, but does in Perl, for example.

Not to nit-pick here, but in perl aren’t “1” and 1 the same type
(“scalar”) but different contexts?

Or is that just a semantic nit?

The context is provided from the program text and affects what gets
pulled out of a scalar; a scalar in Perl has slots for integer value,
number value and string value (being fast & lose with terms here) which
get generated on demand. Usually they are “intuitively” related e.g.

$i = 1; # sets IV slot to 1
print $i . “\n”; # sets PV (string) to contain “1”
print $i + 0.1, “\n” # sets NV to 1

But sometimes the string isn’t the representation of the number (e.g. $!

[mike@ratdog Mail]$ perl -e ‘$! = 1; print $! + 0, “\n$!\n”’
1
Operation not permitted

(Hope I haven’t lied too much here…)

Mike

···

Michael Campbell michael_s_campbell@yahoo.com wrote:


mike@stok.co.uk | The “`Stok’ disclaimers” apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA