The Ruby block is one of the Ruby ways of implementing a closure. And it is the most trivial.
Its domain is:
- Preventing code repetition by extracting its unique part.
- Moving logic into objects (it is about responsibility).
- Hiding internal object design by restricting its API to be more qualified.
class Stack attr_reader :store def initialize *elements @store = elements end endis a simple stack class, offering a reader method, which returns a collection of objects. It can be used like:
stack = Stack.new 'Ruby', 1, { language: 'Ruby' } stack.store.map { |element| element.to_s + ": " + element.object_id.to_s } => Ruby: 14531380 1: 3 {:language=>"Ruby"}: 14531340 stack.store.map { |element| element.to_s + ": " + element.public_methods.join(', ') } => Ruby: <=>, ==, ===, eql?, ... 1: to_s, inspect, -@, +, ... {:language=>"Ruby"}: rehash, to_hash, to_h, to_a, ...The code duplication is obvious. Not tot mention the exposure of the internal storage. Furthermore the public reader method can be more specific about its intention:
class Stack def initialize *elements @store = elements end def stringify @store.map { |element| element.to_s + ": " + yield(element).to_s } end endThe reader method has been removed and the new stringify method offers a stringification of the stack object. The key word yield is a placeholder for the block, where it is processed. The iterating element is assigned to yield as the parameter (the number of parameters for yield in general can vary from zero to whatever).
The stringifying messages to the stack can be sent like:
stack = Stack.new 'Ruby', 1, { language: 'Ruby' } stack.stringify { |element| element.object_id } => Ruby: 13656480 1: 3 {:language=>"Ruby"}: 13656440 stack.stringify { |element| element.public_methods.join(', ') } => Ruby: <=>, ==, ===, eql?, ... 1: to_s, inspect, -@, +, ... {:language=>"Ruby"}: rehash, to_hash, to_h, to_a, ...The messages results are analog to the original example, but the refactored code is more intentional and DRY.
Supported by Ruby 1.9.3
Keine Kommentare:
Kommentar veröffentlichen