#ruby #oop #object #methods
#ruby #ооп #объект #методы
Вопрос:
Допустим, у меня есть объект Ruby с именем Foo
. Результатом этого кода будет следующее:
Foo.bar.baz #=> "bar baz"
Как я мог бы этого добиться. (Я знаю, что это кажется бессмысленным и, вероятно, нарушает несколько соглашений, мне просто было любопытно посмотреть, как этого можно достичь.
Комментарии:
1. Вероятно, вы захотите попробовать создать его с помощью
method_missing
вFoo
классе.
Ответ №1:
Ужасным хакерским способом сделать эту ужасную хакерскую вещь было бы использовать method_missing .
class Ouch
def initialize
@log = ""
end
def method_missing(method)
if @log.empty?
@log = method.to_s
else
@log = " #{method}"
end
self
end
def run
@log
end
end
Теперь вы можете сделать:
Foo = Ouch.new
Foo.bar.baz.run
>> "bar baz"
Это говорит о том, что если вы передаете экземпляр Ouch
метода, которого он не знает (ничего, кроме run), возьмите новый из этого метода и добавьте его в строку журнала, хранящуюся как переменная экземпляра (@log) внутри вашего экземпляра. Наконец, вам нужна какая-нибудь функция извлечения, например run, чтобы сообщить объекту, что вы закончили и хотели бы вернуть накопленный журнал. Надеюсь, это поможет.
[ПРАВИТЬ / ПРАВИТЬ код]
Для полной ясности, method_missing — это «волшебная» функция Ruby, которая вызывается всякий раз, когда метод вызывается для объекта, который объект не распознает.
Ответ №2:
class Object
def bar; [(instance_of?(String)? self : nil), "bar"].join(" ") end
def baz; [(instance_of?(String)? self : nil), "baz"].join(" ") end
end
Foo.bar.baz #=> "bar baz"
Foo.baz.bar #=> "baz bar"
Комментарии:
1. Это интересный подход, но я подразумевал, что любой метод будет работать как
Foo.this.will.return.a.string
, как сmethod_missing
или что-то в этом роде.