tags:

views:

569

answers:

2

I have a constructor for an object Program that validates an argument to make sure it is an integer:

def initialize(programid,*other_args)
  unless programid.is_a?(Integer) then
    raise TypeError
  end
  @programid = programid
  @name = other_args['name']
end

and when I create a new instance

my_prog = Program::new(13453)

It gives me this error:

can't convert String into Integer (TypeError)

Which should not be happening because I'm not trying to do a conversion. Any ideas?

A: 
 class Program
  def initialize(*other_args)
    programid   = other_args.shift
    other_args   = other_args.first || {}
    unless programid.is_a?(Integer) then
      raise TypeError
    end
    @programid = programid
    @name = other_args['name']
    puts @name
    puts @programid
  end
end
Program::new(13453)
Program::new(13453,'name'=>"North Wolf")
Subba Rao
Wow, that's great! Thanks!
+1  A: 

The error isn't caused by is_a?

"can't convert String into Integer (TypeError)" is caused by this line:

@name = other_args['name']

other_args is an array in your sample code not a hash - that's why ruby is trying to convert "name" into an Integer (and failing)

If you call a method with the keyword argument syntax, it works as though all the keyword args are bundled into a hash which is supplied as the last argument to the method call.

Notice the difference in method declarations:

Yours:

def initialize(programid,*other_args)

Subba Rao's

def initialize(*other_args)

That's a neat simplification - turn all the arguments into a single hash, shift out the first arg (which the code assumes you have). Then provide a default empty hash as an alternative if you didn't supply any other args:

other_args.first || {}
cartoonfox