Skip to content

Instantly share code, notes, and snippets.

@zhando
Created July 17, 2012 04:53
Show Gist options
  • Save zhando/3127254 to your computer and use it in GitHub Desktop.
Save zhando/3127254 to your computer and use it in GitHub Desktop.
Ruby epiphany
# update: wow, Proc.new's aren't needed for passed blocks - they're procs already!
# One day I caught myself writing this:
toggle_method
some_method
toggle_method
# and then I needed to conditionally run the toggle method so I did this:
toggle_method if requested
some_method
toggle_method if requested
# Nice thing about ruby is after using it for a while you begin asking yourself if there's a better way.
# Enough of repeating yourself - dry it up! So I came up with this:
def toggle_ctl(toggle, &b)
Array.new(2) {
(toggle ? Proc.new { toggle_method } : nil)
}.insert(1, b).compact.map {|e| e[]}[(toggle ? 1 : 0)]
end
# So now I can do this:
toggle_ctl(requested) { do_something }
# Then I found myself writing this:
save = some_flag
some_flag = some_state
do_something
some_flag = save
# Well that looked familiar! So I came up with this for a flag that is an accessor:
# Accessor save, set, (execute block), restore
def assr(obj, a, v, &b)
setter = "#{a.to_s}=".to_sym
save = obj.send a
[Proc.new { obj.send setter, v }, b, Proc.new { obj.send setter, save }].map {|e| e[]}[1]
end
# So now I can do this:
assr(SomeObjectClassModule, :settergetter, some_state) { do_something }
# However! That method assr while terse is still a bit repetitive with those setter calls.
# How about spreading it out over a class?
# accessor save, set, execute block, restore accessor to original state
class Assr
def self.exec(o, a, v, &b)
new(o, a, v).run(b)
end
def initialize(o, a, v)
@obj, @attr, @val, @save = o, a, v, (o.send a)
end
def run(p)
[sr(@val), p, sr(@save)].map {|e| e[]}[1]
end
private
# set, restore
def sr(x)
Proc.new { @obj.send "#{@attr.to_s}=".to_sym, x }
end
end
# Substitute the assr method call above with in this case Assr.exec.
# Sure this is more verbose but I like drying up the repetitive setter code.
# Appreciate any feedback, links to further discussion of drying up code with blocks, procs, etc..
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment