Reputation: 53
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
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:
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.
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)
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 { ... }
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
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
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