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?は 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)

明示的な return は慣用的な 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)は true になります。でこの条件を使用しているため、すべてが逆になっています: " is " は " is not " に変わります。「または」に-そしてそれがあなたの問題です:どちらかがそうでない、の(サブ)インスタンスである場合に呼び出されますが、両方の条件が真の場合にのみ発生させたいです。argnil argself.classunlessargnilargnilargself.classargself.classarg.methargnil argself.class

したがって、に変更&&するか||、に変更unlessしますif(それに応じて条件を書き換えます)

于 2013-11-03T11:34:55.810 に答える
0

あなたが言ったように -私はarg is notと if .Otherwise returnの場合methにやりたいです。arg.methnilarg.is_a C@v

#instance_of?これは、 でメソッドを呼び出すだけで処理できますargnilオブジェクトを明示的にチェックする必要はありません。ifステートメントは、がクラスのインスタンスである場合にのみ、クラスのインスタンスではない場合trueにのみ、として評価されます。そのため、句がとして評価されるため、発生しません。これは実際にあなたのニーズを満たします。節で起こるだろう、クラスのインスタンスになるとき。そして、これがこの行で起こったケースです。argCnil10Carg.methiffalsearg.methifargcx.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 に答える