Ruby: define_method vs. def

Jako ćwiczenie programistyczne napisałem fragment kodu Ruby, który tworzy klasę, tworzy instancje dwóch obiektów z tej klasy, monkeypatuje jeden obiekt i polega na metod_missing na monkeypatch drugiego.

Oto oferta. Działa to zgodnie z przeznaczeniem:

class Monkey

  def chatter
    puts "I am a chattering monkey!"
  end

  def method_missing(m)
    puts "No #{m}, so I'll make one..."
    def screech
      puts "This is the new screech."
    end
  end
end

m1 = Monkey.new
m2 = Monkey.new

m1.chatter
m2.chatter

def m1.screech
  puts "Aaaaaargh!"
end

m1.screech
m2.screech
m2.screech
m1.screech
m2.screech

Zauważysz, że mam parametr dla metody_missing. Zrobiłem to, ponieważ miałem nadzieję, że użyję define_method do dynamicznego tworzenia brakujących metod o odpowiedniej nazwie. Jednak to nie działa. W rzeczywistości nawet używanie define_method ze statyczną nazwą w ten sposób:

def method_missing(m)
  puts "No #{m}, so I'll make one..."
  define_method(:screech) do
    puts "This is the new screech."
  end
end

Kończy się następującym wynikiem:

ArgumentError: wrong number of arguments (2 for 1)

method method_missing   in untitled document at line 9
method method_missing   in untitled document at line 9
at top level    in untitled document at line 26
Program exited.

To, co sprawia, że ​​komunikat o błędzie jest bardziej zdumiewający, to fakt, że mam tylko jeden argumentmethod_missing...

questionAnswers(3)

yourAnswerToTheQuestion