Module: CodeEvents
Overview
Module CodeEvents
enables event-driven programming by giving objects of the including class the ability to define custom observers and callbacks.
class Looper
include CodeEvents
def initialize(range)
@range = range
end
def run(min, max)
self.fire(:start)
@range.each do |i|
self.fire(:minimum, 0, i) && next if i == min
self.fire(:maximum, 0, i) && next if i == max
puts i
end
return self
end
end
looper = Looper.new(1..10) #=> #<Looper:0x34fe78>
looper.upon :start do
puts "The loop has begun"
end
min_proc = Proc.new {|i| puts "Minimum amount reached: %s" % i } #=> #<Proc:0x3e72a9>
max_proc = Proc.new {|i| puts "Maximum amount reached: %s" % i } #=> #<Proc:0x3ea147>
looper.upon(:minimum => min_proc, :maximum => max_proc) #=> #<Looper:0x34fe78>
looper.run(3,8) #=> #<Looper:0x34fe78>
produces:
The loop has begun
1
2
Minimum amount reached: 3
4
5
6
7
Maximum amount reached: 8
9
10
Instance Method Summary collapse
-
#fire(sym, delay, *args) ⇒ Object
call-seq: obj.fire(sym) -> obj obj.fire(sym, delay, arg, …) -> obj.
-
#ignore(sym, &block) ⇒ Object
call-seq: obj.ignore -> obj obj.ignore(sym) -> obj obj.ignore(sym, &proc) -> obj.
-
#upon(sym_or_hash, unignorable, &block) ⇒ Object
call-seq: obj.upon(sym, unignorable = false) { |arg,…| block } -> obj obj.upon(hash) -> obj.
Instance Method Details
#fire(sym, delay, *args) ⇒ Object
call-seq:
obj.fire(sym) -> obj
obj.fire(sym, delay, arg, ...) -> obj
Instructs obj to call the Proc
objects associated with the event sym, then returns obj. Optionally delays the firing of the event by delay milliseconds. The second form allows passing of arguments to the event’s Proc
objects, but if any arguments are passed, the first must be the delay argument.
obj.upon(:A) {|x| puts x } #=> obj
obj.upon(:B) {|y| puts y } #=> obj
obj.upon(:C) { puts 'fire 3' } #=> obj
obj.fire(:A, 500, 'fire 1').fire(:B, 0, 'fire 2').fire(:C)
produces:
fire 2
fire 3
fire 1
71 72 73 74 75 76 77 78 79 80 |
# File 'lib/source/redshift/code_events.rb', line 71 def fire(sym, delay, *args) name = sym.to_sym return self unless @code_events && events_group = @code_events[name] events_group.each do |proc| `var f=function(){return proc.__block__.apply(null,args);}` `if(delay){return setTimeout(f,delay);}` `f()` end return self end |
#ignore(sym, &block) ⇒ Object
call-seq:
obj.ignore -> obj
obj.ignore(sym) -> obj
obj.ignore(sym, &proc) -> obj
Instructs obj to ignore the specified event, then returns obj.
In the first form, all event-related Proc
objects not marked as “unignorable” are removed from obj.
obj.upon(:A, true) { puts '1st executed' } #=> obj
obj.upon(:A) { puts '2nd executed' } #=> obj
obj.upon(:B) { puts '3rd executed' } #=> obj
obj.ignore #=> obj
obj.fire(:A).fire(:B) #=> obj
produces:
1st executed
In the second form, only the ignorable Proc
objects associated with the event sym are removed.
obj.upon(:A, true) { puts '1st executed' } #=> obj
obj.upon(:A) { puts '2nd executed' } #=> obj
obj.upon(:B) { puts '3rd executed' } #=> obj
obj.ignore(:A) #=> obj
obj.fire(:A).fire(:B) #=> obj
produces:
1st executed
3rd executed
In the third form, only the Proc
object passed in as &proc is removed.
proc_1 = Proc.new { puts 'Proc 1 executed' } #=> #<Proc:0x3e78ee>
proc_2 = Proc.new { puts 'Proc 2 executed' } #=> #<Proc:0x3e888a>
obj.upon(:A, &proc_1) #=> obj
obj.upon(:A, &proc_2) #=> obj
obj.ignore(:A, &proc_1) #=> obj
obj.fire(:A) #=> obj
produces:
Proc 2 executed
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/source/redshift/code_events.rb', line 134 def ignore(sym, &block) if sym name = sym.to_sym return self unless @code_events && events_group = @code_events[name] if block events_group.delete(block) unless `block.__block__.__unignorable__` else events_group.each {|proc| self.disregard(name, &proc) } end else @code_events.each_key {|name| self.disregard(name) } end return self end |
#upon(sym_or_hash, unignorable, &block) ⇒ Object
call-seq:
obj.upon(sym, unignorable = false) { |arg,...| block } -> obj
obj.upon(hash) -> obj
Stores a number of Proc
objects to be called when the event sym is fired.
The first form adds block to the array of Proc
objects executed when the event sym is fired, then returns obj. If unignorable is set to true
, the block will be executed when sym fires, regardless of whether it has been ignored.
obj.upon(:A, true) { puts '1st executed' } #=> obj
obj.upon(:A, true) { puts '2nd executed' } #=> obj
obj.upon(:A) { puts '3rd executed' } #=> obj
obj.ignore(:A) #=> obj
obj.fire(:A) #=> obj
produces:
1st executed
2nd executed
The second form takes a hash of Proc
objects keyed by event name, running obj.upon(name, &proc)
on each key-value pair, then returns obj.
proc_1 = Proc.new { puts '1st executed' } #=> #<Proc:0x3e78ee>
proc_2 = Proc.new { puts '2nd executed' } #=> #<Proc:0x3e888a>
obj.upon(:A => proc_1, :B => proc_2) #=> obj
obj.fire(:B) #=> obj
produces
2nd executed
187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/source/redshift/code_events.rb', line 187 def upon(sym_or_hash, unignorable, &block) if sym_or_hash.instance_of?(Hash) sym_or_hash.each {|name,proc| self.upon(name, &proc) } return self else name = sym_or_hash.to_sym @code_events ||= {} @code_events[name] ||= [] @code_events[name] << block `block.__block__.__unignorable__=typeof(unignorable)=='function'?false:unignorable` return self end end |