jh1356
jh1356

Reputation: 53

object.method or method(object) in Ruby?

I'm new at Ruby and currently learning blocks. As far as I see, there are two ways of calling a parameter to be used inside a block. The firs way is for example:

 def function (parameter)
      yield(x)
    end

so we can call the method by using

function{|x| print x}

My question is about defining a method by following the pattern object.method. For example

parameter.function{|x| #something }

How do you define the block to receive the (1..100) object just like, for example, the each method?:

(1..100).each{|x| print x}

Upvotes: 3

Views: 205

Answers (3)

Stefan
Stefan

Reputation: 114188

My question is about defining a method by following the pattern object.method

If you write obj.foo { ... }, Ruby sends the message foo to obj (along with the block argument). It's up to obj to respond to it.

To make an object respond to a message, you usually define a method with the same name. Due to Ruby's method lookup, there are several ways to do so:

Singleton class

You can define a method on the object itself via def obj.foo:

obj = (1..100)

def obj.foo
  yield 1
  yield 2
  yield 3
end

obj.foo { |x| puts x }
# 1
# 2
# 3

This method is exclusive to obj. Technically, it's defined in the object's singleton class.

Module (via extend)

It can also be defined in a Module:

module Foo
  def foo
    yield 1
    yield 2
    yield 3
  end
end

obj = (1..100)
obj.extend(Foo)
obj.foo { ... }

By using extend all methods from the module will be added to obj. (again via its singleton class)

Module (via include)

If you want to change all instances of a given class, you can include the module into their class:

Range.include(Foo)

(1..100).foo { ... }

Class

Last not least, you can (re-) open the class and add the method right there:

class Range
  def foo
    yield 1
    yield 2
    yield 3
  end
end

(1..100).foo { ...}

You generally don't want to alter Ruby's core classes. But for your own classes, this is the usual and preferred way of defining instance methods.

Upvotes: 1

mechnicov
mechnicov

Reputation: 15288

For example you have such method

def function(x)
  yield(x)
end

You can call it as

function("Hello") { |x| puts x } # will print "Hello"

But you can also call it with self:

self.function("Hello") { |x| puts x } # also will print "Hello"

Because actually in first example you call function for main object. You can check it:

self
# => main

So there is no difference in your examples. In Ruby you always apply the method to some object

If you need to define it, just define this method in some class

class MyClass
  def function(x)
    yield(x)
  end
end

And then call it

my_object = MyClass.new
my_object.function("Hello") { |x| puts x } # also will print "Hello"

Upvotes: 0

rohit89
rohit89

Reputation: 5773

You need to define the function for the object. (0..10) is Range.

irb(main):002:0> (0..10).class
=> Range
class Range
  def function
    self.each {|i| yield i}
  end
end

(0..10).function {|i| print i}
#=> 012345678910

Upvotes: 2

Related Questions