Block
Defined
Some_array.each {|value| puts value + 3}
sum = 0
other_array.each do |value|
Sum + = value
puts value/sum end
- A block are somewhat like the "Body of" anonymous method
- Block can take parameters
- Block only works when called by method, if there are parameters in method, the block appears at the last side
Variables in the block
if the name of the local variable of block is the same as the name of the variable in the same scope, then the two are the same. The value of the variable in the block changes the value of the variable outside the block.
sum = 0
[1,2,3,4].each do |value|
Sum + = value
puts Value/sum end
puts sum # => 30
If a variable in block only appears in the block, then it is only a local variable in the block and cannot be referenced outside of the block.
sum = 0 [1,2,3,4].each do |value| Square = value * value sum = Square end puts sum # => puts square # undefined local variable or method ' square ' fo R Main:object <NameError> Parameters to a blocks are always local to a block, even if they have the same name as Loc
Als in the surrounding scope. Value = "some shape" [1,2].each {|value| puts value} puts value # 1 # 2 # Some shape you can define a block-local vari Ables by putting them through s semicolon in the blocks ' parameter list square = ' some shape ' sum = 0 [1,2,3,4].each do |va Lue
square| Square = value * value sum = Square end puts sum # puts square # some shape
- By making square block-local, values assigned inside the "block won't be affect" the value of the variable with the same Nam E in the outer scope.
- Blocks for transactions
- can use blocks to define a chunk of code this must be run under some kind of transnational
Class File
def self.open_and_process (*args)
f = File.Open (*args)
yield f
f.close
End
file.open_and_process ("Testfile", "R") do |file|
While line = File.gets
puts line
end
Blocks Can be Objects
You can convert a blocks into an object, store it in variables, pass it around, and then invoke its code later.
If the last parameter of method has a & symbol (&action), then when this method is invoked, Ruby will find a code block that is converted to an object of class Proc.
Class Procexample
def pass_in_block (&action)
@stored_proc = Action
end
def use_proc (parameter)
@store_proc. Call (parameter) end,
eg = procexample.new
eg.pass_in_block {|param| puts "the parameter is #{param} '
eg.use_proc
# => The parameter is-
def create_block_object (&block) Block End
bo = create_block_object {|param| puts ' you called me with #{param} '}
Bo.call # => You called me with
the Bo.call "Cat" # => you called me with cat
Ruby have two built-in-methods-convert a Blocks to a object:lambda and proc.new
bo = lambda {|param| puts "you called me with #{param}"}
bo.call 99 # => you called me with 99
- Blocks Can be Closures
- Closure:variables in the surrounding scope this are referenced in a blocks remain accessible accessible for the "Life of th" In block and the "the" the "any" Proc object created from this block.
def n_times (thing)
lambda {|n| thing * n}
end
P1 = N_times (a)
P1.call (3) #=> (
4) P2.call >
def power_proc_generator
value = 1
Lambda {value + = value} end
power_proc = Power_proc_gen Erator
puts Power_proc.call # 2
puts Power_proc.call # 4
lambda expression is another shorthand for
lambda {|params| ...}
# is equivalent to the following notation
-> params {...}
# Parmas is optional
Proc1 =-> arg1, arg2 {puts "#{arg1} #{arg2}"}
Proc1.call "Hello", "World"
# => Hello W Orld
proc2 =-> {"Hello World"}
proc2.call # => Hello World
Block Parameter List
Blocks can take default values, Splat args, keyword args and a block parameter
proc =-> A, *b, &block do
puts "a = #{a.inspect}"
puts "b = #{b.inspect}"
Block.call
End Proc.call (1,2,3,4) {puts "in blocks"}
# a = 1
# b = [2,3,4]
# in block