![]() | Is the RedFlag code correct? |
|
01 Jan 2011, 23:48
Filippo Diotalevi (4 posts) |
Ciao Paolo, first of all congrats for the book. I’m really enjoying studying it. I have some problems with the ‘A Better DSL’ code though. Either I’m losing my mind (not impossible, since the book is so dense at times :) or the code of
blocks/monitor_framework/redflag.rb My test is simple: I just create a new file called ‘test2_event.rb’ containing, f.i., the following code # code starts here event "the lake is dry" do @lake_level < 10 end setup do puts "Setting up lake" @lake_level = 5 end # code ends here and I copy the file in both blocks/monitor_framework and blocks/monitor_final After that, I execute the redflag.rb file in both the cases. The system out in the monitor_framework example is the following $ ruby redflag.rb Setting up lake ALERT: the lake is dry Setting up sky Setting up mountains ALERT: the sky is falling Setting up sky Setting up mountains ALERT: it's getting closer The system out in the monitor_final is the following $ ruby redflag.rb Setting up lake ALERT: the lake is dry Setting up lake Setting up sky Setting up mountains ALERT: the sky is falling Setting up lake Setting up sky Setting up mountains ALERT: the lake is dry Setting up lake Setting up sky Setting up mountains ALERT: it's getting closer The behavior is different, and that’s in fact what I was expecting reading the code. The monitor_framework resets @events and @setups for each file execution. The monitor_final has unique copies of setups and events that are shared among all event file execution. As a result, if I have many event files, the last one will run all the previously defined events and setups. Am I correct? Or am I missing something important? Thanks! |
|
01 Jan 2011, 23:57
Filippo Diotalevi (4 posts) |
Attached a revised monitor_final/redflag.rb file that works for me. I added a reset_events method and invoked before loading a file.
#---
# Excerpted from "Metaprogramming Ruby",
# published by The Pragmatic Bookshelf.
# Copyrights apply to this code. It may not be used to create training material,
# courses, books, articles, and the like. Contact us if you are in doubt.
# We make no guarantees that this code is fit for any purpose.
# Visit http://www.pragmaticprogrammer.com/titles/ppmetr for more book information.
#---
lambda {
setups = []
events = {}
Kernel.send :define_method, :reset_events do
setups = []
events = {}
end
Kernel.send :define_method, :event do |name, &block|
events[name] = block
end
Kernel.send :define_method, :setup do |&block|
setups << block
end
Kernel.send :define_method, :each_event do |&block|
events.each_pair do |name, event|
block.call name, event
end
end
Kernel.send :define_method, :each_setup do |&block|
setups.each do |setup|
block.call setup
end
end
}.call
Dir.glob('*events.rb').each do |file|
reset_events
load file
each_event do |name, event|
env = Object.new
each_setup do |setup|
env.instance_eval &setup
end
puts "ALERT: #{name}" if env.instance_eval &event
end
end
|
|
09 Jan 2011, 11:22
Paolo Perrotta (38 posts) |
Ciao, Filippo! |
| You must be logged in to comment |

