Skip to content

Instantly share code, notes, and snippets.

@patmaddox
Created February 12, 2009 08:10
Show Gist options
  • Save patmaddox/62546 to your computer and use it in GitHub Desktop.
Save patmaddox/62546 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'spec'
class Mine
attr_reader :foo, :bar
def initialize
@foo = 'unchanged'
@bar = 'unchanged'
end
def atomic(*ivars, &block)
ivars = instance_variables if ivars.empty?
before_vals = ivars.inject({}) {|h,i| h[i]=instance_variable_get("@#{i}"); h}
begin
instance_eval &block
rescue => e
before_vals.each {|k,v| instance_variable_set("@#{k}", v) }
raise e
end
end
end
describe "atomic changes" do
it "should reraise an error raised" do
lambda {
Mine.new.atomic(:foo, :bar) do
@foo = 'ignore'
@bar = 'ignore'
raise 'an error'
end
}.should raise_error(/an error/)
end
it "should reset the ivars if there's an error" do
o = Mine.new
o.atomic(:foo, :bar) {
@foo = 'changed'
@bar = 'changed'
raise 'an error'
} rescue nil
o.foo.should == 'unchanged'
o.bar.should == 'unchanged'
end
it "should make all ivars atomic if none specified" do
o = Mine.new
o.atomic {
@foo = 'changed'
@bar = 'changed'
raise 'an error'
} rescue nil
o.foo.should == 'unchanged'
o.bar.should == 'unchanged'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment