Class: Module
- Defined in:
- lib/qualitysmith_extensions/module/bool_attr_accessor.rb,
lib/qualitysmith_extensions/module/guard_method.rb,
lib/qualitysmith_extensions/module/bool_attr_accessor.rb,
lib/qualitysmith_extensions/module/attribute_accessors.rb
Overview
Extends the module object with module and instance accessors for class attributes, just like the native attr* accessors for instance attributes.
Instance Method Summary collapse
-
#bool_attr_accessor(*args) ⇒ Object
This creates both a reader and a setter for a boolean (flag) attribute (instance variable).
-
#bool_attr_reader(*args) ⇒ Object
This creates a reader method for a boolean (flag) attribute (instance variable).
-
#bool_attr_setter(*args) ⇒ Object
This creates a setter method for a boolean (flag) attribute (instance variable).
-
#guard_method(guard_method_name, guard_variable) ⇒ Object
A guard method (by this definition anyway) is a method that sets a flag, executes a block, and then returns the flag to its previous value.
- #mattr_accessor(*syms) ⇒ Object
-
#mattr_reader(*syms) ⇒ Object
:nodoc:.
- #mattr_writer(*syms) ⇒ Object
-
#mbool_attr_accessor(*args) ⇒ Object
This creates both a reader and a setter for a boolean (flag) class/module variable.
-
#mbool_attr_reader(*args) ⇒ Object
This creates a reader method for a boolean (flag) class/module variable.
-
#mbool_attr_setter(*args) ⇒ Object
This creates a setter method for a boolean (flag) class/module variable.
-
#mguard_method(guard_method_name, guard_variable) ⇒ Object
See the documentation for guard_method.
Instance Method Details
#bool_attr_accessor(*args) ⇒ Object
This creates both a reader and a setter for a boolean (flag) attribute (instance variable).
bool_attr_accessor :a
is equivalent to
bool_attr_reader :a
bool_attr_setter :a
Examples:
x = Klass.new
x.a! true # sets @a to true
x.a? # => true
x.a! # toggles @a, so that it ends up being false
x.a! # toggles @a, so that it ends up being true
x.a! false # sets @a to false
125 126 127 128 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 125 def bool_attr_accessor(*args) bool_attr_reader *args bool_attr_setter *args end |
#bool_attr_reader(*args) ⇒ Object
This creates a reader method for a boolean (flag) attribute (instance variable).
bool_attr_reader :a
is equivalent to
def a?
@a ? true : @a
end
Example:
class Foo
def set_it
@a = true
end
end
x = Foo.new
x.a? # => false
x.set_it
x.a? # => true
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 39 def bool_attr_reader(*args) = (if args.last.is_a?(Hash) then args.pop else {} end) # These options aren't used here, per se, but it allows us to have bool_attr_accessor pass along same args to both bool_attr_reader and bool_attr_setter. make = {} args.each { |a| make["#{a}?".to_sym] = %{ def #{a}?(true_value=true) @#{a} ? true_value : @#{a} end } } module_eval make.values.join("\n"), __FILE__, __LINE__ make.keys end |
#bool_attr_setter(*args) ⇒ Object
This creates a setter method for a boolean (flag) attribute (instance variable).
bool_attr_setter :a
is equivalent to
def a!(switch=Exception)
if switch == Exception
@a = !@a
else
@a = switch ? true : false
self
end
end
This setter method can either be used to set it directly to true or false or to toggle it.
Examples:
x = Klass.new
x.a! true # sets @a to true
x.a! # toggles @a, so that it ends up being false
x.a! # toggles @a, so that it ends up being true
x.a! false # sets @a to false
Use :allow_nil if you want it to be a tri-state flag – that is, if you need to be able to set it to nil as well as true and false.
bool_attr_setter :a, :b, :allow_nil => true
x.a! nil # sets @a to nil
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 83 def bool_attr_setter(*args) = (if args.last.is_a?(Hash) then args.pop else {} end) make = {} args.each { |a| make["#{a}!".to_sym] = %{ def #{a}!(switch=Exception) if switch == Exception @#{a} = !@#{a} else #{ options[:allow_nil] ? "@#{a} = switch ? true : switch" : "@#{a} = switch ? true : false" } self end end } } module_eval make.values.join("\n"), __FILE__, __LINE__ make.keys end |
#guard_method(guard_method_name, guard_variable) ⇒ Object
A guard method (by this definition anyway) is a method that sets a flag, executes a block, and then returns the flag to its previous value. It ensures that the flag is set during the execution of the block.
In the simplest case, you’d use it like this:
class A
guard_method :disable_stupid_stuff!, :@stupid_stuff_disabled
end
a = A.new
a.disable_stupid_stuff! do # Causes @stupid_stuff_disabled to be set to true
# Section of code during which you don't want any stupid stuff to happen
end # Causes @stupid_stuff_disabled to be set back to false
# Okay, a, you can resume doing stupid stuff again...
If you want your guard method to disable the flag rather than enable it, simply pass false to the guard method.
These calls can be nested however you wish:
a.guard_the_fruit! do
a.guard_the_fruit!(false) do
assert_equal false, a.guarding_the_fruit?
end
assert_equal true, a.guarding_the_fruit?
end
You can also use the guard methods as normal flag setter/clearer methods by simply not passing a block to it. Hence
a.guard_the_fruit!
will simply set @guarding_the_fruit to true, and
a.guard_the_fruit!(false)
will set @guarding_the_fruit to false.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/qualitysmith_extensions/module/guard_method.rb', line 53 def guard_method(guard_method_name, guard_variable) raise ArgumentError.new("Expected an instance variable name but got #{guard_variable}") if guard_variable !~ /^@([\w_]+)$/ guard_variable.to_s =~ /^@([\w_]+)$/ # Why didn't the regexp above set $1 ?? class_eval do bool_attr_accessor $1.to_sym end module_eval " def \#{guard_method_name}(new_value = true, &block)\n old_guard_state, \#{guard_variable} = \#{guard_variable}, new_value\n if block_given?\n begin\n returning = yield\n ensure\n \#{guard_variable} = old_guard_state\n returning\n end\n end\n end\n End\nend\n", __FILE__, __LINE__+1 |
#mattr_accessor(*syms) ⇒ Object
42 43 44 45 |
# File 'lib/qualitysmith_extensions/module/attribute_accessors.rb', line 42 def mattr_accessor(*syms) mattr_reader(*syms) mattr_writer(*syms) end |
#mattr_reader(*syms) ⇒ Object
:nodoc:
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/qualitysmith_extensions/module/attribute_accessors.rb', line 6 def mattr_reader(*syms) syms.each do |sym| class_eval(" unless defined? @@\#{sym}\n @@\#{sym} = nil\n end\n \n def self.\#{sym}\n @@\#{sym}\n end\n\n def \#{sym}\n @@\#{sym}\n end\n EOS\n end\nend\n", __FILE__, __LINE__+1) |
#mattr_writer(*syms) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/qualitysmith_extensions/module/attribute_accessors.rb', line 24 def mattr_writer(*syms) syms.each do |sym| class_eval(" unless defined? @@\#{sym}\n @@\#{sym} = nil\n end\n \n def self.\#{sym}=(obj)\n @@\#{sym} = obj\n end\n\n def \#{sym}=(obj)\n @@\#{sym} = obj\n end\n EOS\n end\nend\n", __FILE__, __LINE__+1) |
#mbool_attr_accessor(*args) ⇒ Object
This creates both a reader and a setter for a boolean (flag) class/module variable.
mbool_attr_accessor :a
is equivalent to
mbool_attr_reader :a
mbool_attr_setter :a
Works for both classes and modules.
221 222 223 224 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 221 def mbool_attr_accessor(*args) mbool_attr_reader *args mbool_attr_setter *args end |
#mbool_attr_reader(*args) ⇒ Object
This creates a reader method for a boolean (flag) class/module variable.
mbool_attr_reader :a
is equivalent to
def self.a?
@@a ? true : @@a
end
Works for both classes and modules.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 147 def mbool_attr_reader(*args) = (if args.last.is_a?(Hash) then args.pop else {} end) # These options aren't used here, per se, but it allows us to have bool_attr_accessor pass along same args to both bool_attr_reader and bool_attr_setter. make = {} args.each { |a| make["#{a}?".to_sym] = %{ def self.#{a}?(true_value=true) @@#{a} ? true_value : @@#{a} end } } module_eval make.values.join("\n"), __FILE__, __LINE__ make.keys end |
#mbool_attr_setter(*args) ⇒ Object
This creates a setter method for a boolean (flag) class/module variable.
mbool_attr_setter :a
is equivalent to
def self.a!(switch=Exception)
if switch == Exception
@@a = !@@a
else
@@a = switch ? true : false
self
end
end
Works for both classes and modules.
Use :allow_nil if you want it to be a tri-state flag – that is, if you need to be able to set it to nil as well as true and false.
mbool_attr_setter :a, :b, :allow_nil => true
C.a! nil # sets @@a to nil
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/qualitysmith_extensions/module/bool_attr_accessor.rb', line 183 def mbool_attr_setter(*args) = (if args.last.is_a?(Hash) then args.pop else {} end) make = {} args.each { |a| # Initialize it first so that we won't have any NameErrors. module_eval %{ @@#{a} = nil if !defined?(@@#{a}) }, __FILE__, __LINE__ make["#{a}!".to_sym] = %{ def self.#{a}!(switch=Exception) if switch == Exception @@#{a} = !@@#{a} else #{ options[:allow_nil] ? "@@#{a} = switch ? true : switch" : "@@#{a} = switch ? true : false" } self end end } } module_eval make.values.join("\n"), __FILE__, __LINE__ make.keys end |
#mguard_method(guard_method_name, guard_variable) ⇒ Object
See the documentation for guard_method. mguard_method does the same thing, only it creates a class (or module) method rather than an instance method and it uses a class (or module) variable rather than an instance variable to store the guard state.
Example:
mguard_method :guard_the_fruit!, :@@guarding_the_fruit
mguard_method :use_assert_equal_with_highlight!, :@@always_use_assert_equal_with_highlight
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/qualitysmith_extensions/module/guard_method.rb', line 81 def mguard_method(guard_method_name, guard_variable) raise ArgumentError.new("Expected a class variable name but got #{guard_variable}") if guard_variable !~ /^@@[\w_]+$/ guard_variable.to_s =~ /^@@([\w_]+)$/ class_eval do mbool_attr_accessor $1.to_sym end module_eval " class << self\n def \#{guard_method_name}(new_value = true, &block)\n old_guard_state, \#{guard_variable} = \#{guard_variable}, new_value\n if block_given?\n begin\n returning = yield\n ensure\n \#{guard_variable} = old_guard_state\n returning\n end\n end\n end\n end\n End\nend\n", __FILE__, __LINE__+1 |