Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How method name is converted into a symbol in Ruby?

Tags:

ruby

I am trying to understand Ruby and it's not clear for me, how Ruby converts name of method into a Symbol?

In method definition we give it a name meth

module Mod
  def meth
    puts 'm'
  end
end

But if we want to check if a method exists, we pass the symbol :meth as a parameter to method_defined

Mod.method_defined?(:meth)
=> true 

Please, help me understand, how does this work?

like image 797
igor_rb Avatar asked Mar 27 '26 01:03

igor_rb


2 Answers

This is due to ruby's method invocation syntax: You can call a method just by referencing its name, without any further syntax like brackets () needed.

Now, if the method_defined? method would take the method itself as an argument, there would be no way to do so without actually invoking the method and thereby producing an error if the method would not exist:

Mod.method_defined?(meth) 
#=> NameError: undefined local variable or method `meth'

With symbols, there is no invocation taking place, it is just normally instantiated and not producing any error. Behind the curtains, method_defined? can then lookup if a method exists by the name the symbol references without producing any error.

like image 112
Beat Richartz Avatar answered Mar 29 '26 17:03

Beat Richartz


it's not clear for me, how Ruby converts name of method into :symbol?

That's the way Method#name works, it returns the name of the method as a symbol:

m = "foo".method(:size)     #=> #<Method: String#size>
m.name                      #=> :size
m.call                      #=> 3

All methods referencing other methods usually work this way. For example, Object#methods returns a array of method names:

"foo".methods
#=> [:<=>, :==, :===, :eql?, :hash, :casecmp, :+, :*, ...]

In method definition we give it name meth ... but if we want check, does any method exist, we give into method_defined symbol :meth

meth would be a reference to a variable or another method, whereas :meth is just a symbol:

meth = :foo
Mod.method_defined? meth   #=> false, equivalent to Mod.method_defined? :foo
Mod.method_defined? :meth  #=> true
like image 40
Stefan Avatar answered Mar 29 '26 16:03

Stefan