Podle dopisu v ML ruby-talk(51000)
od Christiana Szegedy
The Ruby way (via yield, simply linked list): (A complete implemenatation for a change):
Příklad 4.1. A
class List def add(obj) @first = [@first,obj] end def each e = @first while e yield e[1] e = e[0] end end end l = List.new l.add("hello") l.add("world") l.each do |s| puts s end
The yield in the "each" function calls the block for each object of the list. The example above prints:
hello world
Drawbacks: none.
Příklad 4.2. Example B): Traversing a data structure recursively:
class Array def traverse_rec for e in self do if e.kind_of? Array e.traverse_rec else yield e end end end end [ [1,2] [1,3,[4,[5] ],2,[3,4] ] ].traverse_rec do |el| puts el; end
outputs all elementes of the tree recursively. (The tree is implemented as an array of (possible arrays of (possible ....))... )
Do something with each element of the a data structure (minor variation of example 1):
Příklad 4.3. Example C)
class List def add(obj) @first = [@first,obj] end def map e = @first while e e[1] = yield e[1] end end end l = List.new l.add("hello") l.add("world") l.map do |s| s.length end
Each element of the list is replaced by its length.
Do something according to a dynamic criterion (Sum up all elements of a list conditionally)
Příklad 4.4. Example D)
class List def add(*objs) objs.each do |obj| @first = [@first,obj] end end def sum_if e = @first sum = 0; while e sum += e[1] if yield e[1] end end end l = List.new l.add(1,3,4,5,6,2,1,6); l.add_if do |i| (i%3)==0 end
The last function sums all elements of the list which are divisible by 3. I hope it gives you some insides about the power of yield.
Regards, Christian