Skip to content

Instantly share code, notes, and snippets.

@cho45
Created February 20, 2014 14:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cho45/9115072 to your computer and use it in GitHub Desktop.
Save cho45/9115072 to your computer and use it in GitHub Desktop.
module Guard
@@guards = []
def guard(&block)
set_trace_func(lambda {|event, file, line, id, binding, klass|
# p [event, file, line, id, binding, klass]
case event
when "call", "c-call"
for g in @@guards
g[:count] += 1
end
when "return", "c-return"
out_of_scope = @@guards.each {|g|
g[:count] -= 1
}.select {|g| g[:count] < 0 }
@@guards -= out_of_scope
for g in out_of_scope
g[:block].call
end
set_trace_func(nil) if @@guards.empty? && id != :set_trace_func
end
}) if @@guards.empty?
@@guards << {
block: block,
count: 1
}
end
end
include Guard
require "rspec"
RSpec::Core::Runner.autorun
describe Guard do
before do
@events = []
end
it "should execute guard block as it is out of scope" do
instance_eval do # new scope
@events << :enter
guard { @events << :end1 }
guard { @events << :end2 }
@events << :leave
end
expect(@events).to eq([
:enter,
:leave,
:end1,
:end2
])
end
it "should works correctly with nested scope" do
instance_eval do # new scope
@events << :enter1
guard { @events << :end1_1 }
guard { @events << :end1_2 }
instance_eval do
@events << :enter2
guard { @events << :end2_1 }
guard { @events << :end2_2 }
@events << :leave2
end
@events << :leave1
end
expect(@events).to eq([
:enter1,
:enter2,
:leave2,
:end2_1,
:end2_2,
:leave1,
:end1_1,
:end1_2,
])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment