rubysome_array.each { |value| puts value + 3 } sum = 0 other_array.each do |value| sum += value puts value / sum end
rubysum = 0 [1,2,3,4].each do |value| sum += value puts value / sum end puts sum # => 30
rubysum = 0 [1,2,3,4].each do |value| square = value * value sum += square end puts sum # => 30 puts square # undefined local variable or method 'square' for main:Object <NameError>
rubyvalue = "some shape" [1,2].each { |value| puts value } puts value # 1 # 2 # some shape
rubysquare = "some shape" sum = 0 [1,2,3,4].each do |value; square| square = value * value sum += square end puts sum # 30 puts square # some shape
By making square block-local, values assigned inside the block will not affect the value of the variable with the same name in the outer scope.express
You can use blocks to define a chunk of code that must be run under some kind of transnational controlruby
rubyclass File def self.open_and_process(*args) f = File.open(*args) yield f f.close end end File.open_and_process("testfile","r") do |file| while line = file.gets puts line end end
You can convert a block into an object, store it in variables, pass it around, and then invoke its code later.ide
若是 method 的最後一個參數前面有 & 符號 (&action), 那麼當此 method 被調用時,Ruby 會找一個 code block, 這個 code block 被轉換成 class Proc 的一個對象。ui
rubyclass ProcExample def pass_in_block(&action) @stored_proc = action end def use_proc(parameter) @store_proc.call(parameter) end end eg = ProcExample.new eg.pass_in_block { |param| puts "The parameter is #{param}" } eg.use_proc(99) # => The parameter is 99
rubydef create_block_object(&block) block end bo = create_block_object { |param| puts "You called me with #{param}" } bo.call 99 # => You called me with 99 bo.call "cat" # => You called me with cat
Ruby have two built-in methods that convert a block to an object: lambda and Proc.newlua
rubybo = lambda { |param| puts "You called me with #{param}" } bo.call 99 # => You called me with 99
Closure: Variables in the surrounding scope that are referenced in a block remain accessible accessible for the life of that block and the life on any Proc object created from that block.code
rubydef n_times(thing) lambda {|n| thing * n} end p1 = n_times(23) p1.call(3) #=> 69 p2.call(4) #=> 92 def power_proc_generator value = 1 lambda { value += value } end power_proc = power_proc_generator puts power_proc.call # 2 puts power_proc.call # 4
lambda 表達式的另外一種簡寫方式對象
rubylambda { |params| ... } # 與下面的寫法等價 -> params { ... } # parmas 是可選的
rubyproc1 = -> arg1, arg2 {puts "#{arg1} #{arg2}"} proc1.call "hello", "world" # => hello world proc2 = -> { "Hello World" } proc2.call # => Hello World
Blocks can take default values, splat args, keyword args and a block parameterthree
rubyproc = -> a, *b, &block do puts "a = #{a.inspect}" puts "b = #{b.inspect}" block.call end proc.call(1,2,3,4) {puts "in block"} # a = 1 # b = [2,3,4] # in block
A Ruby iterator is simple a method that can invoke a block of code.element
- Block 通常是跟着 method 出現的, 而且 block 中的代碼不必定會執行
- 若是 method 中有
yield
, 那麼它的block 中的代碼會被執行- Block 能夠接收參數,和返回 value
rubydef two_times yield yield end two_times { puts "Hello" } # Hello # Hello
rubydef fib_up_to(max) i1, i2 = 1. 1 while i1 <= max yield i1 i1, i2 = i2, i1 + i2 end end fib_up_to(1000) { |f| print f, " " } # 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
i1
會做爲 parameter 傳入到 block 中, 賦值給 block 的 argument f
。each is probable the simplest iterator - all it does is yield successive elements of its collection.rem
ruby[1, 3, 5, 7, 9].each { |i| puts i } # 1 # 3 # 5 # 7 # 9
A blocl may also return a value to the method. The value of the last expression evaluated in the block is passed back to the method as the value of the yield.
rubyclass Array def find each do |value| return value if yield(value) end end end [1,3,4,7,9].find { |v| V*V > 30 } # => 7
Which takes each element from the collection and passes it to the block. The results returned by the block are used to construct a new array
ruby["H", "A", "L"].collect { |x| x.succ } # => ["I", "B", "M"]
The inject method lets you accumulate a value across the members of a collection.
ruby[1,3,5,7].inject { |sum, element| sum + element } # => 16 # sum = 1, element = 3 # sum = 4, element = 5 # sum = 9, element = 7 # sum = 16 [1,3,5,6].inject { |product, element| product*element } # => 105
If inject
is called with no parameter, it uses the first element of the collections as the initial value and starts the iteration with the second value.
上面代碼的另外一種簡便寫法:
ruby[1,3,5,7].inject(:+) # => 16 [1,3,5,7]/inject(:*) # => 105
Iterators 不單單可以訪問 Array 和 Hash 中的數據, 和能夠和 I/O 系統交互
rubyf = File.open("testfile") f.each do |line| puts "The line is: #{line}" end f.close produces: The line is: This is line one The line is: This is line two The line is: This is line three
目前,個人理解是 Parameter 是實際參數,而 Argument 是形式參數