1
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

如果arg 不是 nil 并且 if ,meth我想做。否则返回。但我想这部分是不正确的。无法弄清楚出了什么问题。arg.metharg.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
4

3 回答 3

1

10.nil?是假的,因此(arg.nil?) && !(arg.is_a? self.class)是假的,鉴于其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
于 2013-11-03T11:35:11.720 回答
0

(arg.nil?) && !(arg.is_a? self.class)如果argnil arg不是 的(子)实例,则条件为真self.class。你在 中使用这个条件unless,所以一切都颠倒了:“argnil”变成“arg不是nil”,“arg不是”的(子)实例self.class变成“arg是”的(子)实例self.class,最重要的是 - “和”变成进入“或” - 这就是你的问题:arg.meth如果arg不是nil 或者 arg是(子)实例,则调用self.class它 - 但你只希望它在两个条件都为真时发生。

所以 - 要么更改&&||,要么更改unlessif(并相应地重写条件)

于 2013-11-03T11:34:55.810 回答
0

正如你所说 -如果arg 不是并且如果.Otherwise 返回,meth我想做。arg.methnilarg.is_a C@v

这可以通过简单地调用#instance_of?on方法来处理arg。您不需要明确检查nil对象。该if语句将被评估为true,仅当arg是类的实例时。您的类的C实例nil也不10C,因此arg.meth不会发生,因为if子句将被评估为false。这实际上满足了您的需求。arg.meth将发生在if子句中,whenarg将是 class 的实例c。而这就是发生在这一行的情况x.meth(y)

这是您要获取的代码:

class C
   attr_accessor :v
   def initialize(arg)
     @v = arg
   end
   def meth(arg=nil)
     return arg.meth if arg.instance_of?(self.class)
     @v
   end
end 

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

x.meth # => "first"
x.meth(y) # => "second"
x.meth(10) # => "first"
于 2013-11-03T11:36:59.927 回答