Created
July 17, 2012 04:53
-
-
Save zhando/3127254 to your computer and use it in GitHub Desktop.
Ruby epiphany
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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