Hi,
let’s say I’ve got a class Point2D to write, it must have 2 methods to
initialize :
- one with cartesian coordinates i.e : p = Point2D.new(x,y) given the
numbers x and y;
- a second with polar coordinates i.e : p = Point2D.new(R,theta) given
the radius R>0 and an angle theta;
How can I manage this ?
Thanks.
kibleur.christophe wrote:
Hi,
let’s say I’ve got a class Point2D to write, it must have 2 methods to
initialize :
- one with cartesian coordinates i.e : p = Point2D.new(x,y) given the
numbers x and y;
- a second with polar coordinates i.e : p = Point2D.new(R,theta) given
the radius R>0 and an angle theta;
How can I manage this ?
One way would be to take keyword arguments and figure out which you were
given.
class Point2D
def initialize( params )
if params.has_key? :r and params.has_key? :theta
## initialize from polar
elsif params.has_key? :x and params.has_key? :y
## initialize from cartesian
else
raise ArgumentError.new( “You must provide either :r and :theta OR
:x and :y” )
end
end
end
cart = Point2D.new( :x => 42, :y => -4 )
polar = Point2D.new( :r => 3.14159, :theta => (Math::PI/4) )
raise ArgumentError.new( "You must provide either :r and :theta OR
:x and :y" )
end
end
end
cart = Point2D.new( :x => 42, :y => -4 )
polar = Point2D.new( :r => 3.14159, :theta => (Math::PI/4) )
Hi Mike,
What you’ve proposed is a fine idea, but I think that it’s important to
be clear about your terminology. Ruby doesn’t currently have keyword
arguments. In the example that you’ve provided you are passing a hash
with symbols for keys into the initialize method and not using
keywords.
Regards,
Matthew J Desmarais
desmarm wrote:
What you’ve proposed is a fine idea, but I think that it’s important to
be clear about your terminology. Ruby doesn’t currently have keyword
arguments. In the example that you’ve provided you are passing a hash
with symbols for keys into the initialize method and not using
keywords.
Oop, you’re of course correct. It’s more “I can’t believe it’s not
keyword arguments”, now with 30% less calories than regular argument
passing (yum, syntactic sugar!).
You can also define alternate constructors:
class Point2D
class << self
def new_xy( x, y )
new.set_xy( x, y )
end
def new_rt( r, t )
new.set_rt( r, t )
end
end
def set_xy( x, y )
@x, @y = x, y
end
def set_rt( r, t )
@r, @t = r, t
end
end
p = Point2D.new_xy( x, y )
p = Point2D.new_rt( R, theta )
T.
Quoting Mike F. [email protected]:
the radius R>0 and an angle theta;
How can I manage this ?
If you are always storing cartesian coordinates internally, I’d
suggest introducing a different factory method for creating points
from polar coordinates. For example:
class Point2D
attr_accessor :x, :y
def initialize( x, y )
@x, @y = x, y
end
def self.new_polar( r, theta )
new( r * Math::cos( theta ), r * Math::sin( theta ) )
end
end
examples:
cart = Point2D.new( 42, -4 )
polar = Point2D.new_polar( 3.14159, Math::PI / 4 )
-mental
Thanks for all your answers, in fact, my class was already written with
the last mentioned code method.
class Point
attr_accessor :abs, :ord, :name, :cart
def initialize(abs,ord,name="")
@abs = abs
@ord = ord
@name = name
@cart = true
end
def to_s
“#@name : (#{@abs}, #{@ord})”
end
def ==(unPoint)
unPoint.abs = abs and unPoint.ord = ord
end
def Point.new_polaire(rho, theta, name)
@cart = false
@name = name
unPoint = new(rhocos(theta),rhosin(theta),@name)
return unPoint
end
end
…but I dislike the calling syntax. I thought it was possible to write
several constructors calls like in Java, ie :
void Move(Vector2D vector) {
center.x += vector.x;
center.y += vector.y;
}
void Move(double x,double y) {
center.x += x;
center.y += y;
}
So, my idea was bad : Ruby is not Java !