#-- # Author:: Tyler Rick # Copyright:: Copyright (c) 2007 QualitySmith, Inc. # License:: Ruby License # Submit to Facets?:: Yes # Developer notes:: # * Based on /usr/lib/ruby/gems/1.8/gems/facets-1.8.54/lib/facets/core/module/attr_tester.rb # * Hey Thomas, don't you think Module#attr_tester should only create the read-only a? method and have another method that creates the writer (like there how we have attr_reader, _writer, and _accessor?) ? "tester" does not imply "setter" in my mind... #++ class Module # This creates two methods for each given variable name. One is used to test # the attribute and the other is used to set or toggle it. # # attr_tester :a # # is equivalent to # # def self.a? # @@a ? true : @@a # end # # def self.a!(switch=Exception) # if switch == Exception # @@a = !@@a # else # @@a = switch ? true : @@a # self # end # end # # Works for both classes and modules. # def mattr_tester(*args) 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}?(true_value=true) @@#{a} ? true_value : @@#{a} end } make["#{a}!".to_sym] = %{ def self.#{a}!(switch=Exception) if switch == Exception @@#{a} = !@@#{a} else @@#{a} = switch ? true : @@#{a} self end end } } module_eval make.values.join("\n"), __FILE__, __LINE__ return make.keys end end # _____ _ # |_ _|__ ___| |_ # | |/ _ \/ __| __| # | | __/\__ \ |_ # |_|\___||___/\__| # =begin test require 'test/unit' require 'rubygems' require 'qualitysmith_extensions/object/ignore_access' class TheTest < Test::Unit::TestCase class C mattr_tester :a end module M mattr_tester :a end def test_cattr_tester_exclamation C.access.class_variable_set(:@@a, false) assert_equal(false, C.a?) # otherwise would have been nil C.a! assert_equal(true, C.a?) C.a! assert_equal(false, C.a?) end def test_cattr_tester_return C.a! assert_equal(true, C.a?) C.a!("whatever") assert_equal(true, C.a?) # Still returns a boolean even though we set it to a string. end def test_mattr_tester_exclamation assert_equal(nil, M.a?) M.a! assert_equal(true, M.a?) M.a! assert_equal(false, M.a?) end def test_mattr_tester_return M.a! assert_equal(true, M.a?) M.a!("whatever") assert_equal(true, M.a?) # Still returns a boolean even though we set it to a string. end end =end