Forum: Ruby different methods for initializing one object?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Aac8251adf22be080507c8327ecc2caa?d=identicon&s=25 kibleur.christophe (Guest)
on 2005-12-09 22:01
(Received via mailing list)
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.
357558a6682f4d6624594763d9acdb35?d=identicon&s=25 Mike Fletcher (fletch)
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) )
0817571d150afead454f4220007042fe?d=identicon&s=25 desmarm (Guest)
on 2005-12-09 22:29
(Received via mailing list)
<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
357558a6682f4d6624594763d9acdb35?d=identicon&s=25 Mike Fletcher (fletch)
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!).
45196398e9685000d195ec626d477f0e?d=identicon&s=25 transfire (Guest)
on 2005-12-09 22:46
(Received via mailing list)
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.
912c61d9da47754de7039f4271334a9f?d=identicon&s=25 mental (Guest)
on 2005-12-09 22:50
(Received via mailing list)
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
Aac8251adf22be080507c8327ecc2caa?d=identicon&s=25 kibleur.christophe (Guest)
on 2005-12-10 00:03
(Received via mailing list)
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 !
This topic is locked and can not be replied to.