Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble negating `is_a?` in Ruby

Tags:

ruby

class C
   attr_accessor :v
   def initialize(arg)
     @v = arg
   end
   def meth(arg=nil)
     return arg.meth unless (arg.nil?) && !(arg.is_a? self.class)
     @v
   end
end

In meth I want to do arg.meth if arg is not nil and if arg.is_a?C. Otherwise return @v. But I guess this part !(arg.is_a? self.class) is incorrect. Couldn't figure out whats wrong.

x = C.new("first")
y = C.new("second")

x.meth #=> "first"
x.meth(y) #=> "second"
x.meth(10) #=> I was expecting 'first'

But I get NoMethodError: undefined method `meth' for 10:Fixnum

I do not want to negate arg.nil? I would like to achieve arg.is_not_a?

Update: Looks like my question is confusing. I am trying to clarify here

if the argument passed to meth is not nil and is of type C then 
  call arg.meth 
else 
  return @v
end
like image 877
Bala Avatar asked Aug 06 '26 07:08

Bala


1 Answers

10.nil? is false, and thus (arg.nil?) && !(arg.is_a? self.class) is false, and given how unless works, your method is going to try to call 10.meth.

Replace that line with either:

return arg.meth if !arg.nil? && (arg.is_a? self.class)

or

return arg.meth unless arg.nil? || !(arg.is_a? self.class)

EDIT: since arg.is_a? self.class implies !arg.nil? the above is redundant, and should really just be:

return arg.meth if arg.is_a? self.class

or, if you really really want to use unless:

return arg.meth unless !(arg.is_a? self.class)

The explicit return isn't idiomatic Ruby, so something like this would probably be ideal

def meth(arg=nil)
  arg.is_a?(self.class) ? arg.meth : @v
end
like image 174
Amit Kumar Gupta Avatar answered Aug 09 '26 06:08

Amit Kumar Gupta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!