残念ながら、これは不可能です。
これは、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_proc
to_float
to_bool