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
在meth
中,如果arg不是nil且arg.meth
,我想arg.is_a?C
。否则返回@v
。但我想这部分!(arg.is_a? self.class)
是不正确的。无法弄清楚什么是错的。
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
我不想否定arg.nil?
我希望实现arg.is_not_a?
更新:看起来我的问题令人困惑。我想在这里澄清一下
if the argument passed to meth is not nil and is of type C then
call arg.meth
else
return @v
end
答案 0 :(得分:1)
10.nil?
为false,因此(arg.nil?) && !(arg.is_a? self.class)
为false,并且考虑到unless
的工作方式,您的方法将尝试调用10.meth
。
将该行替换为:
return arg.meth if !arg.nil? && (arg.is_a? self.class)
或
return arg.meth unless arg.nil? || !(arg.is_a? self.class)
编辑:由于arg.is_a? self.class
暗示!arg.nil?
,上述内容是多余的,应该只是:
return arg.meth if arg.is_a? self.class
或者,如果你真的想要使用,除非:
return arg.meth unless !(arg.is_a? self.class)
显式返回不是惯用的Ruby,所以像这样的东西可能是理想的
def meth(arg=nil)
arg.is_a?(self.class) ? arg.meth : @v
end
答案 1 :(得分:0)
如果(arg.nil?) && !(arg.is_a? self.class)
为arg
并且 nil
不是arg
的(子)实例,则条件self.class
将为真。您在unless
中使用了这一条件,因此一切都相反:“arg
nil
”变为“arg
不是nil
”,“{{ 1}}不是arg
的(子)实例“变成”self.class
是arg
的(子)实例“,最重要的是 - ”和“变成”或“ - 这就是您的问题:如果self.class
不是arg.meth
或 arg
是nil
的(子)实例,则会调用arg
- 但是如果两个条件都为真,你只希望它发生。
所以 - 将self.class
更改为&&
,或将||
更改为unless
(并相应地重写条件)
答案 2 :(得分:0)
正如你所说 - 在meth
我希望arg.meth
如果arg不是nil
而arg.is_a C
。否则返回{{1} }。
这可以通过在@v
上简单地调用方法#instance_of?
来处理。您无需明确检查arg
对象。仅当nil
是类if
的实例时,true
语句才会被评估为arg
。C
和nil
都不是类10
的实例,所以C
不会发生,因为arg.meth
子句将被评估为if
。这实际上满足了您的需求。false
子句中会发生arg.meth
,而if
将成为类arg
的实例。这就是c
这一行中发生的情况。
以下是您要获取的代码:
x.meth(y)