Hi, let's say I've got a class Point2D to write, it must have 2 methods to initialize : 1. one with cartesian coordinates i.e : p = Point2D.new(x,y) given the numbers x and y; 2. 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.

on 2005-12-09 22:01

on 2005-12-09 22:15

kibleur.christophe wrote: > Hi, > let's say I've got a class Point2D to write, it must have 2 methods to > initialize : > 1. one with cartesian coordinates i.e : p = Point2D.new(x,y) given the > numbers x and y; > 2. 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) )

on 2005-12-09 22:29

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

on 2005-12-09 22:34

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!).

on 2005-12-09 22:46

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.

on 2005-12-09 22:50

Quoting Mike Fletcher <lemurific+rforum@gmail.com>: > > 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

on 2005-12-10 00:03

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(rho*cos(theta),rho*sin(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 !