1

I came across this code while trying to learn about creating your own method_missing method, and I don't understand it. What I don't understand are these parts: method_sym[-1] == "=" and method_sym[0..-2] What do they refer to? I tried some simulations in irb, but this just returned some weird stuff.

Could anyone break it down for me? I would really appreciate it. Thanks!

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
Olivier Girardot
  • 389
  • 4
  • 16

1 Answers1

3

method_sym, i.e. the first argument of method_missing is the Symbol instance representing the name of the method. So, for example, if you call

a.foo

and Ruby fails to find foo method, a.method_missing(:foo) will be called.

Next, Symbol#[] method is used to return nth character of the symbol or some characters range if you pass Range into it. -1 passed into this method represent "last character". -2 represents 'the character before the last one' etc. So:

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

args represents all the arguments passed into missing method. So, if you call your method with:

a.foo(arg1, arg2, arg3)

args in missing_method will be:

[arg1, arg2, arg3]

Methods in Ruby can be named with = at the end , that's how you create setter methods, like:

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

It's regular method and A.new.foo = some_value is only a syntactic sugar, under the hood, it's equivalent to A.new.foo=(some_value). So if you call

b.foo = 'value'

and the b.foo= is not defined, Ruby is going to call:

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

thus the = as method_sym[-1].

Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
  • Thank you that is very helpful. I didn't get that the first argument of the method_missing (here method_sym) was the first argument of the missing method. In that case, are *args the remaining arguments, or all the arguments (including the first one) ? – Olivier Girardot Apr 01 '20 at 14:13
  • Also, I am still not sure what all this does. For example, why would method_sym[-1] be equal to "=" ? – Olivier Girardot Apr 01 '20 at 14:14
  • 1
    @OlivierGirardot I answered to both your questions. – Marek Lipka Apr 01 '20 at 14:19
  • 1
    When you use a splat (`*`) it gathers up the remaining arguments. `**` does the same thing but for keyword arguments. – max Apr 01 '20 at 14:20
  • Thank you very much! All this is very new to me so I am going to need to study that closely. It is much clearer than before, thanks a lot for your help :) – Olivier Girardot Apr 01 '20 at 14:35