Abhishek Yadav
ரூபீ ப்ரோக்ராமர்
Co-organizer: Chennai.rb
loop
while
for..in
Iterators
Iterators are more popular than the others
An iterator operates on some kind of list,
It expects a block as argument
[1,2,3].each do |x|
puts (x**2)
end
each | is the iterator |
[1,2,3] | is the list |
do..end | is the block |
object.method(argument)
Follows this familiar method invocation pattern in object oriented programming
[1,2,3] is an object of the Array class.
The Array class has defined the method each.
The each method takes one argument.
So,
We are creating a lump of code and passing it to the each method as an argument:
{ |x| puts(x**2) }
The each method can execute it.
To execute a block, the yield keyword is used.
yield 12 will invoke the given block with 12 as argument
Its very similar to given_block.call(12)
Array's each method is implemented in similar way
def foo
yield 12
end
foo {|x| x**2 } #=> 144
def bar(&given_block) # Very similar
given_block.call(12)
end
bar {|x| x**2 } #=> 144
class Array
# Approximate implementation of each
def each
list = self
i = 0
loop do
break if i >= list.length
yield list[i] # <= given_block.call(list[i])
i += 1
end
end
end
And x is the argument in both
# So,
{ |x| puts x**2 }
# is the same as
do|x|
puts(x**2)
end
a = { |x| puts x**2 } # SyntaxError
a = Proc.new do |x| # works
puts x**2
end
a = lambda{ |x| puts x**2 } # works
a = ->(x){ puts x**2 } # works
class Array
def myeach
return unless block_given?
arr = self
len = arr.length
i = 0
loop do
yield arr[i]
break if arr[i] == nil # Loop stops at nil
i += 1
i = 0 if i >= len
end
end
alias_method :old_each, :each
alias_method :each, :myeach
end
range = [1..Float::INFINITY]
range.lazy.map {|x| x**2 }.first(5) # [1, 4, 9, 16, 25]
Abhishek Yadav
ரூபீ ப்ரோக்ராமர்
Co-organizer: Chennai.rb