\PythonとRubyのdefって何が違ふんです?/

Pythonのdefは関数、Rubyのdefはメソッドを定義します。両者の違いはdefがネストすると現れます。

Pythonでは、ネストしたdefではローカル関数が定義されます。ローカル関数はその場で使われるだけで、外部には影響は及ぼしません(グローバル変数に代入したり、returnで返したりしなければ)。

$ python
>>> class Spam:
...   def ham(self):
...     def egg():
...       print('egg', end='')
...     print('egg', end='')
...     egg()
...
>>> s = Spam()
>>> s.egg()
AttributeError: 'Spam' object has no attribute 'egg'
>>> s.ham()
ham
egg
>>> s.egg()
AttributeError: 'Spam' object has no attribute 'egg'


一方Rubyでは、defはネストしていようがいまいが、クラスにメソッドを定義するものです。メソッドの中でメソッド定義が呼ばれると、呼び出される毎にメソッドを定義するメソッドが定義されます(わかりづらい!)。

$ irb --prompt-mode simple
>> class Spam
>>   def ham()
>>     def egg()
>>       puts 'egg'
>>     end
>>     puts 'ham'
>>     egg
>>   end
>> end
=> nil
>> s = Spam.new
=> #
>> s.egg
NoMethodError: undefined method `egg' for #
>> s.ham
ham
egg
=> nil
>> s.egg #eggメソッドが追加されている!
egg
=> nil


RubyPythonのローカル関数のようなものが欲しいときは、Procまたはlambdaを使う。
このdefの仕様はあまり役に立たないので、Ruby 2.0で変更される可能性があるらしい。

Matzにっき(2010-06-16)
Rubyist Magazine - Rubyist Hotlinks 【第 23 回】 yhara さん