Есть ли эквиваленты методу Ruby в других языках? - PullRequest
21 голосов
/ 19 мая 2010

В Ruby у объектов есть удобный метод, называемый method_missing, который позволяет обрабатывать вызовы методов для методов, которые даже не были (явно) определены:

Вызывается Ruby, когда obj отправляется сообщение, которое он не может обработать. Символ - это символ для вызываемого метода, а аргументы - любые аргументы, которые были переданы ему. По умолчанию интерпретатор выдает ошибку при вызове этого метода. Однако возможно переопределить метод, чтобы обеспечить более динамичное поведение. В приведенном ниже примере создается класс Roman, который отвечает на методы с именами, состоящими из римских цифр, и возвращает соответствующие целочисленные значения.

class Roman
 def romanToInt(str)
   # ...
 end
 def method_missing(methId)
   str = methId.id2name
   romanToInt(str)
 end
end

r = Roman.new
r.iv      #=> 4
r.xxiii   #=> 23
r.mm      #=> 2000

Например, Ruby on Rails использует это для разрешения вызовов таких методов, как find_by_my_column_name.

У меня вопрос: какие другие языки поддерживают эквивалент method_missing и как вы реализуете эквивалент в своем коде?

Ответы [ 15 ]

3 голосов
/ 19 мая 2010

Actionscript 3.0 имеет класс Proxy, который можно расширить для обеспечения этой функциональности.

dynamic class MyProxy extends Proxy {
  flash_proxy override function callProperty(name:*, ...rest):* {
    try {
      // custom code here
    }
    catch (e:Error) {
      // respond to error here
    }
}  
2 голосов
/ 12 мая 2011

Его эквивалент в Io использует метод forward.

Из документов:

Если объект не отвечает на сообщение, он вызовет свой метод «forward», если он есть ...

Вот простой пример:

Shout := Object clone do (
    forward := method (
        method_missing := call message name
        method_missing asUppercase
    )
)

Shout baz println     # => BAZ

/ I3az /

2 голосов
/ 20 мая 2010

В CFML (ColdFusion, Railo, OpenBD) обработчик событий onMissingMethod(), определенный внутри компонента, будет получать неопределенные вызовы методов для этого компонента. Аргументы missingMethodName и missingMethodArguments автоматически передаются, что позволяет динамически обрабатывать отсутствующий вызов метода. Это механизм, который облегчал создание неявных схем установки / получения, прежде чем они начали встраиваться в различные механизмы CFML.

2 голосов
/ 19 мая 2010

Tcl имеет нечто подобное. Каждый раз, когда вы вызываете любую команду, которая не может быть найдена, будет вызвана процедура unknown . Хотя это не то, чем вы обычно пользуетесь, иногда это может быть удобно.

1 голос
/ 20 мая 2010

Boo имеет IQuackFu - уже есть отличная сводка по SO на how-can-i-intercept-a-method-call-in-boo

Вот пример:

class XmlObject(IQuackFu):
_element as XmlElement 

def constructor(element as XmlElement):
    _element = element 

def QuackInvoke(name as string, args as (object)) as object:
    pass # ignored 

def QuackSet(name as string, parameters as (object), value) as object:
    pass # ignored 

def QuackGet(name as string, parameters as (object)) as object:
    elements = _element.SelectNodes(name)
    if elements is not null:
        return XmlObject(elements[0]) if elements.Count == 1
        return XmlObject(e) for e as XmlElement in elements 

override def ToString():
    return _element.InnerText 
...