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.
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)’
====================================
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.
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.
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.
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
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
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.
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
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
Method names that mean something in the domain language.
Gives class method creation methods that are clearly spelled out. Not
just another variant of new with another parameter
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
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.
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 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
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
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.
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
···
On Thu, Jun 19, 2003 at 05:40:02PM +0900, Sam Griffith 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?
···
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:
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?
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. $!