Ruby: мне нужна помощь в понимании следующего кода, включающего method_missing (method, * args, & block) - PullRequest
1 голос
/ 01 апреля 2020

Я сталкивался с этим кодом, пытаясь узнать о создании собственного метода method_missing, и я не понимаю его. Что я не понимаю, так это следующие части: method_sym [-1] == "=" и method_sym [0 ..- 2] На что они ссылаются? Я попробовал некоторые симуляции в irb, но это только вернуло некоторые странные вещи.

Может кто-нибудь сломать это для меня? Я был бы очень признателен. Спасибо!

class UberHash
  def method_missing(method_sym, *args, &block)
    if method_sym[-1] == "="
      instance_variable_set("@#{method_sym[0..-2]}", args[0])
    else
      instance_variable_get("@#{method_sym}")
    end
  end
end

1 Ответ

3 голосов
/ 01 апреля 2020

method_sym, то есть первый аргумент method_missing - это экземпляр Symbol, представляющий имя метода. Так, например, если вы вызываете

a.foo

и Ruby не удается найти метод foo, будет вызван a.method_missing(:foo).

Далее используется метод Symbol#[] вернуть n-ый символ символа или диапазон некоторых символов, если вы введете в него Range. -1 переданный в этот метод представляет "последний символ". -2 представляет «символ перед последним» и т.д. c. Итак:

symbol = :foo
symbol[-1]
# => "o"
symbol[0..-2]
# => "fo"

args представляет все аргументы, переданные в отсутствующий метод. Таким образом, если вы вызовете ваш метод с помощью:

a.foo(arg1, arg2, arg3)

args в missing_method будет:

[arg1, arg2, arg3]

Методы в Ruby могут быть названы с помощью = в в конце концов, именно так вы создаете методы установки, например:

class A
  def foo=(value)
    @foo = value
  end
end

Это обычный метод, а A.new.foo = some_value - это всего лишь синтактический c сахар, под капотом он эквивалентен A.new.foo=(some_value). Поэтому, если вы звоните

b.foo = 'value'

, а b.foo= не определен, Ruby будет звонить:

b.method_missing(:foo=, 'value')

, таким образом, = как method_sym[-1].

...