Skip to content

Instantly share code, notes, and snippets.

@bil-bas
Created October 14, 2012 16:25
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 bil-bas/3889080 to your computer and use it in GitHub Desktop.
Save bil-bas/3889080 to your computer and use it in GitHub Desktop.
Yah boo, attr accessor with magic and history. Feel free to use it to cheat if you are a king-sized idiot who doesn't want to learn!
class Class
def attr_accessor_with_history(attr_name)
attr_reader attr_name
class_eval %Q{
# Create the attribute's history getter
def #{attr_name}_history
@#{attr_name}_history ||= [nil]
end
# Create the attribute's setter
def #{attr_name}=(value)
#{attr_name}_history << value
@#{attr_name} = value
end
}
end
end
# Run the file with "rspec attr_accessor_with_history.rb" to run the tests.
if defined? RSpec
class Foo
attr_accessor_with_history :foo
attr_accessor_with_history "bar"
end
describe Class do
let(:subject) { Foo.new }
let(:another_subject) { Foo.new }
describe "reader" do
it "should initially be nil" do
subject.bar.should eq nil
end
it "should give the latest value" do
subject.bar = 1
subject.bar = 2
subject.bar.should eq 2
end
it "should maintain separate values for each attribute" do
subject.bar = 1
subject.foo = 2
subject.bar.should eq 1
end
it "should maintain separate values for each object" do
subject.bar = 1
another_subject.bar = 2
subject.bar.should eq 1
end
end
describe "*_history" do
it "should initially record the value of nil" do
subject.bar_history.should eq [nil]
end
it "should record new values in the history" do
subject.bar = 1
subject.bar = 2
subject.bar_history.should eq [nil, 1, 2]
end
it "should maintain separate histories for each attribute" do
subject.bar = 1
subject.foo = 2
subject.bar_history.should eq [nil, 1]
end
it "should maintain separate histories for each object" do
subject.bar = 1
another_subject.bar = 2
subject.bar_history.should eq [nil, 1]
end
end
end
end
=begin
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s # make sure it's a string
attr_reader attr_name # create the attribute's getter
attr_reader attr_name+"_history" # create bar_history getter
class_eval "your code here, use %Q for multiline strings"
end
end
class Foo
attr_accessor_with_history :bar
end
f = Foo.new()
puts f
f.bar = 1
f.bar = 2
f.bar_history
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment