トップ «前の日記(2009-05-17) 最新 次の日記(2009-05-19)» 編集

日々の破片

著作一覧

2009-05-18

_ どこがprotected

うーん。
class Foo
  protected
  def foo()
    puts 'foo'
  end
end
class Bar < Foo
  def foo()
    puts 'bar'
  end
end
 
x = Bar.new
x.foo

上のプログラムは動く(1.8.7、1.9.1とも)。ということは、protectedは継承クラスでは維持されないということなんだろう。

そこで次のように変えてみる。

class Foo
  protected
  def foo()
    puts 'foo'
  end
end
class Bar < Foo
  protected   # 追加
  def foo()
    puts 'bar'
  end
end
 
x = Bar.new
x.foo

確かに、そうであって欲しい動作を得られる。

C:\temp>ruby -v protected.rb
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-mswin32]
protected.rb:15: protected method `foo' called for #<+Bar:0x27af420> (NoMethodError)
or)

そこでメソッドbooをFooに追加する。

class Foo
  def boo(f)
    f.foo  # 別のインスタンスのfooを呼ぶ
  end
  protected
  def foo()
    puts 'foo'
  end
end
class Bar < Foo
  protected
  def foo()
    puts 'bar'
  end
end
 
x = Foo.new
x.boo(Foo.new)
x.boo(Bar.new)

実行する。

C:\temp>ruby -v protected.rb
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-mswin32]
foo  …… OK
protected.rb:3:in `boo': protected method `foo' called for #<Bar:0x1b77504> (NoMethodError)
        from protected.rb:19:in `<main>'

うーむ。どうしろと。最初の例から、protectedは継承されないから継承クラスでprotectedを付けた。しかし、そうすると継承元クラスからの呼び出しもできなくなる。しかしレシーバを指定したいからprivateではなくprotectedにしているのだから、これはどちらかがおかしくはないか(というよりも、継承先で呼び出しが可能なメソッドをprotectedと称するということなんだろうなぁ、きっと)。

おれにとっては、継承先にprotectedが引き継がれることが自然だと思うが、Rubyの考え方ではかくあるのだろう。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

ジェズイットを見習え