Ruby Typing?

Hi everyone. I'm very new to ruby development. I coming form .Net side
of things. Is there any way in ruby to verify the type of whatever
parameter your passing to a method and give the user a good message. For
example:

def Add_two_numbers(x,y)
    ....if type of x is not integer
         throw an error "x was expected to be an integer and is not"
   .....if type of y is not an integer
       throw an error "y was expected to be an integer and is not"
end

When i just hit a bug where i was expecting an array of comments and
instead a single comment was passed (in the constructor). The code
exploded with i tried to do "@comments << comments[0]" because @comments
was not an array with an error message like "undefined function '<<'
which took me awhile to figure out. Want to try to prevent this in the
future if possible.

thanks...

···

--
Posted via http://www.ruby-forum.com/.

Sometimes it's best to let the errors occur, there's already a certain
amount of error-handling in Ruby.

Anyway, this should do what you want:

def Add_two_numbers(x,y)
[x,y].each { |num|
fail ArgumentError, "#{num} is not a number" unless num.is_a? Fixnum
}
x + y
end

···

--
Posted via http://www.ruby-forum.com/.

Hi everyone. I'm very new to ruby development. I coming form .Net side
of things. Is there any way in ruby to verify the type of whatever
parameter your passing to a method and give the user a good message.

Welcome to the wonderful world of Ruby!

Your Ruby experience will be much more smoothly if you get rid of the
static typing mindset. It's not the way people use Ruby. But many people
coming from statically typed languages fear that their Ruby programs will
be totally unsafe if they do not ensure types are enforced.

You'll find a lot of explanations under the term "duck typing".

For
example:

def Add_two_numbers(x,y)
    ....if type of x is not integer
         throw an error "x was expected to be an integer and is not"
   .....if type of y is not an integer
       throw an error "y was expected to be an integer and is not"
end

I once blogged about creating classes which represent numbers. The central
concept revolves around method #coerce.
http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

In the specific case of your method above, I'd simply do

def add_two_numbers(x, y)
  x.to_int + y.to_int
end

This will reliably fail if x or y do not represent integer values.

When i just hit a bug where i was expecting an array of comments and

instead a single comment was passed (in the constructor). The code
exploded with i tried to do "@comments << comments[0]" because @comments
was not an array with an error message like "undefined function '<<'
which took me awhile to figure out. Want to try to prevent this in the
future if possible.

Writing tests helps a great deal avoiding that. :slight_smile:

Kind regards

robert

···

On Fri, Mar 29, 2013 at 5:06 PM, John n/a <lists@ruby-forum.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

You could also try x.to_int + y.to_int and use respond_to?(:to_int)
for detection. Equally with #to_ary. Duck typing!

Better use Integer for the test because Fixnums turn to Bignums from a
certain number on. Using #to_int or Integer() is a simpler approach as it
includes the exception throwing code with a meaningful error message
already:

irb(main):023:0> Integer("x")
ArgumentError: invalid value for Integer(): "x"
        from (irb):23:in `Integer'
        from (irb):23
        from /usr/bin/irb:12:in `<main>'
irb(main):024:0> "x".to_int
NoMethodError: undefined method `to_int' for "x":String
        from (irb):24
        from /usr/bin/irb:12:in `<main>'

Kind regards

robert

···

On Fri, Mar 29, 2013 at 5:38 PM, Joel Pearson <lists@ruby-forum.com> wrote:

Sometimes it's best to let the errors occur, there's already a certain
amount of error-handling in Ruby.

Anyway, this should do what you want:

def Add_two_numbers(x,y)
[x,y].each { |num|
fail ArgumentError, "#{num} is not a number" unless num.is_a? Fixnum
}
x + y
end

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

and x.kind_of?(Fixnum) in addition to Adam's points

···

On Fri, Mar 29, 2013 at 9:47 AM, Adam Prescott <adam@aprescott.com> wrote:

You could also try x.to_int + y.to_int and use respond_to?(:to_int)
for detection. Equally with #to_ary. Duck typing!

--
vizualize.me/cliffrosson

Why use respond_to?(:to_int) for detection if you write x.to_int + y.to_int
anyway? That's redundant work and _not_ Duck Typing.

Cheers

robert

···

On Fri, Mar 29, 2013 at 5:47 PM, Adam Prescott <adam@aprescott.com> wrote:

You could also try x.to_int + y.to_int and use respond_to?(:to_int)
for detection. Equally with #to_ary. Duck typing!

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Hm, true. :slight_smile: I guess there might be cases where you want a specific
error message in the method itself, versus the method's caller? Or
maybe if there are other implicit conversions you can fall back to.
Probably rescue-able. Agreed, though.

···

On 29 March 2013 22:19, Robert Klemme <shortcutter@googlemail.com> wrote:

Why use respond_to?(:to_int) for detection if you write x.to_int + y.to_int
anyway? That's redundant work and _not_ Duck Typing.