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
lambda
s 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:
- A method is implicitly passed the object on which it was called.
- 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
How to Break from Nested Loops in Ruby
How to Use the Rails Helper "Distance_Of_Time_In_Words" in Plain Old Ruby (Non-Rails)
How to Avoid Deprecation Messages from Rubygems
Creating a Thread-Safe Temporary File Name
Using a Class Object in Case Statement
The Encoding That Notepad++ Just Calls "Ansi", Does Anyone Know What to Call It for Ruby
Is There a "Main" Method in Ruby Like in C
Rails: Render View from Outside Controller
How to Add a Primary Key to a Table in Rails
Heroku Wrongly Detecting My Node App as a Ruby App
Ruby Bundler Multiple Sources in Gemfile
Ruby on Rails Upload File Problem Odd Utf8 Conversion Error
Why Is 'Return a or B' a Void Value Expression Error in Ruby
How to Fix Hanging Popen3 in Ruby