Ruby Functions VS Methods

in ruby is there a distinction between a method and function

In Ruby, there are not two separate concepts of methods and functions. Some people still use both terms, but in my opinion, using "function" when talking about Ruby is incorrect. There do not exist executable pieces of code that are not defined on objects, because there is nothing in Ruby that is not an object.

As Dan pointed out, there's a way to call methods that makes them look like functions, but the underlying thing is still a method. You can actually see this for yourself in IRB with the method method.

> def zomg; puts "hi"; end
#=> nil
> method(:zomg)
#=> #<Method: Object#zomg>
> Object.private_instance_methods.sort
#=> [..., :zomg]
# the rest of the list omitted for brevity

So you can see, the method zomg is an instance method on Object, and is included in Object's list of private instance methods.

Ruby functions vs methods

lambdas in Ruby are objects of class Proc. Proc objects don't belong to any object. They are called without binding them to an object.

Methods are objects of either class Method or UnboundMethod, depending on whether they're bound or unbound. See the explanation here. Unbound methods can't be called until they're bound to an object.

lambda{|x| x}.class      # => Proc
lambda{|x| x}.call(123) # => 123

class Foo
def bar(baz)
baz
end
end

puts Foo.new.method(:bar).class # => Method
puts Foo.new.method(:bar).call(123) # => 123

puts Foo.instance_method(:bar).class # => UnboundMethod
puts Foo.instance_method(:bar).call(123) # => throws an exception

You can bind an UnboundMethod to an object and then call it. But you can't bind a Proc to an object at all. Proc objects can however capture local variables in the surrounding scope, becoming closures.

What's the difference between a method and a function?

A function is a piece of code that is called by name. It can be passed data to operate on (i.e. the parameters) and can optionally return data (the return value). All data that is passed to a function is explicitly passed.

A method is a piece of code that is called by a name that is associated with an object. In most respects it is identical to a function except for two key differences:

  1. A method is implicitly passed the object on which it was called.
  2. A method is able to operate on data that is contained within the class (remembering that an object is an instance of a class - the class is the definition, the object is an instance of that data).

(this is a simplified explanation, ignoring issues of scope etc.)

What is the difference between a method and a proc object?

In brief:

a Method object is "bound" to an object so that self points to that object when you call the method, and a Proc doesn't have that behavior; self depends on the context in which the Proc was created/called.

However:

You said in your question that "methods are not objects," but you have to be careful to distinguish between "method" and Method.

A "method" is a defined set of expressions that is given a name and put into the method table of a particular class for easy lookup and execution later:

class Foo
def my_method
return 123
end
end

Foo.new.my_method
# => 123

A Method object (or similarly an UnboundMethod object) is an actual Ruby object created by calling method / instance_method / etc. and passing the name of a "method" as the argument:

my_Foo = Foo.new

my_Method = my_Foo.method(:my_method)
# => #<Method: Foo#my_method>

my_Method.call
# => 123

my_UnboundMethod = Foo.instance_method(:my_method)
# => #<UnboundMethod: Foo#my_method>

my_UnboundMethod.bind(my_Foo).call
# => 123

A Proc object is a set of expressions that is not given a name, which you can store for later execution:

my_proc = Proc.new { 123 }
my_proc.call
# => 123

You may find it useful to read the RDoc documentation for UnboundMethod, Method, and Proc. The RDoc pages list the different instance methods available to each type.

Why use procs instead of methods?

Proc is a callable piece of code. You can store it in a variable, pass as an argument and otherwise treat it as a first-class value.

Why not just use a method?

Depends on what you mean by "method" here.

class Foo
def bar
puts "hello"
end
end

f = Foo.new

In this code snippet usage of method bar is pretty limited. You can call it, and that's it. However, if you wanted to store a reference to it (to pass somewhere else and there call it), you can do this:

f = Foo.new
bar_method = f.method(:bar)

Here bar_method is very similar to lambda (which is similar to Proc). bar_method is a first-class citizen, f.bar is not.

For more information, read the article mentioned by @minitech.

What are the practical differences between a module method and a class method in Ruby?

tl;dr: There are no class methods and module methods in Ruby, only instance methods. Considering that they are both just instance methods, and thus the same thing, there cannot possibly be any difference.


There is no such thing as a "class method" or a "module method" in Ruby. Ruby has exactly one kind of method: instance methods.

We sometimes use the word "class method" or "module method" out of convenience when talking about a certain pattern of using instance methods, but there is no such concept in Ruby. "Class methods" and "module methods" are really just singleton methods of an object which just happens to be an instance of the Module class or the Class class. There is absolutely no difference whatsoever between a singleton method of an object which happens to be an instance of Class, Module, String, Array, Hash, Object, Foo, Bar, Whatever, or Garbledigookidoo.

Oh. Did I mention? Singleton methods don't exist, either. Again, it is a word we use for certain kinds of usages of methods, but they are really just regular boring old instance methods of the singleton class of an object.

However, "instance method of the singleton class of foo" and "instance method of the singleton class of Foo, where Foo is an instance of Class" are really long, and so we shorten them to "singleton method of foo" and "class method of Foo" out of convenience, knowing full well that those are fictions that don't actually exist in the language.

Unlike Java, which has three different kinds of methods (instance methods, static methods, and constructors (which are kinda-sorta like methods)), Ruby has exactly one kind of method: instance methods. No class methods, no module methods, no global methods, no top-level methods, no static methods, no constructors. It does, however, have three kinds of classes: regular classes, singleton classes, and include classes (the latter being classes that get synthesized and injected into the inheritance hierarchy when you call include or prepend). These classes differ mainly in whether methods like Object#class, Class#superclass, and Class#ancestors display them or suppress them. Singleton classes are suppressed by all of them, include classes by the first two, but shown by ancestors.

Difference between . and #

The hash format (Class#method) is not valid ruby, but is used in documentation to describe an instance method.

Class methods are typically documented using a double-colon (Class::method).

You will see examples of both in the ruby docs (e.g. http://www.ruby-doc.org/core-1.9.3/String.html)

The dot format is used in code when actually calling a class method (Class.method), though I have seen some people (unfortunately) use it interchangeably with either the double-colon or hash in documentation.



Related Topics



Leave a reply



Submit