14

これをやりたい

lol = Klass.new(values)

unless lol 
   print "false"
end

lol.other_method  # it is not nil or false, it is a Klass instance!

しかし、この場合、lolはnilまたはfalseではなく、何らかの内部値に基づいてfalseとして機能できるオブジェクトです。私はこの選択肢があります

lol = Klass.new(values)

unless lol.to_bool
   print "false"
end

しかし、それは醜い私見です。

私はFalseClassを拡張するか、==で遊ぶことを考えていましたが、成功しませんでした。何か案は?

4

2 に答える 2

16

残念ながら、これは不可能です。

これは、Rubyがオブジェクト指向ではない厄介なケースの1つです。OOでは、あるオブジェクトが別のオブジェクトをシミュレートできる必要があります(実際、誰に尋ねるかによって、これはOOの定義そのものです。OOはシミュレーションから生まれたことを思い出してください)が、次のようなオブジェクトを作成することはできません。をシミュレートしfalseます。

forこれは、Rubyでは、条件付き制御構造が言語に組み込まれ、メッセージ送信に変換されないのに対し、他のOO言語では、通常のメッセージ送信であるためです(または、Rubyの場合と同様に、少なくともメッセージ送信に変換されます。each)。たとえば、Smalltalkでは、ブール値は実際にはラムダ計算で知っているブール値のチャーチエンコードを使用して実装され、Rubyに変換されると次のようになります。

class FalseClass
  def if(&block)
    # do nothing
  end

  def if_then_else(then_lambda, else_lambda)
    else_lambda.()
  end

  def not
    true
  end

  def and(&block)
    self
  end

  def or(&block)
    block.()
  end
end

そして、それTrueClassは単なる鏡像です:

class TrueClass
  def if(&block)
    block.()
  end

  def if_then_else(then_lambda, else_lambda)
    then_lambda.()
  end

  def not
    false
  end

  def and(&block)
    block.()
  end

  def or(&block)
    self
  end
end

そして、のようなものの代わりに

if 2 < 3 then foo end
if 2 < 3 then bar else baz end

あなたが持っているだろう

(2 < 3).if { foo }
(2 < 3).if_then_else(-> { bar }, -> { baz })

# using the new keyword arguments in Ruby 2.0, it almost reads like Smalltalk:
class FalseClass
  def if(then: -> {}, else: -> {})
    else.()
  end
end

class TrueClass
  def if(then: -> {}, else: -> {})
    then.()
  end
end

(2 < 3).if(then: -> { bar }, else: { baz })

falseそうすれば、それぞれのメソッドを実装するだけで、シミュレートするオブジェクトを簡単に作成できます。

他の場合、あるオブジェクトが本当に絶対に特定のクラスのインスタンスでなければならず、正しいプロトコルを話すだけではない場合、Rubyはエスケープハッチを提供します。たとえば、メソッドが本当にArray引数としてを必要とする場合、最初に呼び出しto_aryを試みて、少なくともオブジェクトをに変換する機会を与えますArray。同じことが、、、to_strなどにも当てはまります。ただしto_int、同等のプロトコルはありません。to_procto_floatto_bool

于 2013-01-22T00:01:34.553 に答える
6

簡単な答え:これをしないでください

長い答えは、Rubyにはfalseと評価されるものが2つしかないfalseということです:とnil。文字通り、他のすべてが真であると評価されます。

多くのアプリケーションはこの動作に依存しており、なんとかしてこれを変更すると誤動作する可能性があります。これは、1を偶数として定義するようなものです。それは問題を引き起こすでしょう。

于 2013-01-21T19:18:37.520 に答える