提交 cfd9e05a 编写于 作者: J Jeremy Kemper

attr_internal to support namespacing and deprecation

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4692 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 678f8cbb
*SVN* *SVN*
* attr_internal to support namespacing and deprecation. Like attr_* except backed by internally-named instance variable. Set attr_internal_naming_format to change the format from the default '@_%s'. [Jeremy Kemper]
# def foo() @foo__rofl end
# def foo=(v) @foo__rofl = v end
self.attr_internal_naming_format = '@%s__rofl'
attr_internal :foo
* Raise fully qualified names upon name errors. #5533 [lars@pinds.com, Nicholas Seckar] * Raise fully qualified names upon name errors. #5533 [lars@pinds.com, Nicholas Seckar]
* Add extention to obtain the missing constant from NameError instances. [Nicholas Seckar] * Add extention to obtain the missing constant from NameError instances. [Nicholas Seckar]
......
require File.dirname(__FILE__) + '/module/inclusion' require File.dirname(__FILE__) + '/module/inclusion'
require File.dirname(__FILE__) + '/module/attribute_accessors' require File.dirname(__FILE__) + '/module/attribute_accessors'
require File.dirname(__FILE__) + '/module/attr_internal'
require File.dirname(__FILE__) + '/module/delegation' require File.dirname(__FILE__) + '/module/delegation'
require File.dirname(__FILE__) + '/module/introspection' require File.dirname(__FILE__) + '/module/introspection'
require File.dirname(__FILE__) + '/module/loading' require File.dirname(__FILE__) + '/module/loading'
......
class Module
# Declare an attribute reader backed by an internally-named instance variable.
def attr_internal_reader(*attrs)
attrs.each do |attr|
module_eval "def #{attr}() #{attr_internal_ivar_name(attr)} end"
end
end
# Declare an attribute writer backed by an internally-named instance variable.
def attr_internal_writer(*attrs)
attrs.each do |attr|
module_eval "def #{attr}=(v) #{attr_internal_ivar_name(attr)} = v end"
end
end
# Declare attributes backed by 'internal' instance variables names.
def attr_internal_accessor(*attrs)
attr_internal_reader *attrs
attr_internal_writer *attrs
end
alias_method :attr_internal, :attr_internal_accessor
private
mattr_accessor :attr_internal_naming_format
self.attr_internal_naming_format = '@_%s'
def attr_internal_ivar_name(attr)
attr_internal_naming_format % attr
end
end
require File.dirname(__FILE__) + '/../../abstract_unit'
class AttrInternalTest < Test::Unit::TestCase
def setup
@target = Class.new
@instance = @target.new
end
def test_attr_internal_reader
assert_nothing_raised { @target.attr_internal_reader :foo }
assert !@instance.instance_variables.include?('@_foo')
assert_raise(NoMethodError) { @instance.foo = 1 }
@instance.instance_variable_set('@_foo', 1)
assert_nothing_raised { assert_equal 1, @instance.foo }
end
def test_attr_internal_writer
assert_nothing_raised { @target.attr_internal_writer :foo }
assert !@instance.instance_variables.include?('@_foo')
assert_nothing_raised { assert_equal 1, @instance.foo = 1 }
assert_equal 1, @instance.instance_variable_get('@_foo')
assert_raise(NoMethodError) { @instance.foo }
end
def test_attr_internal_accessor
assert_nothing_raised { @target.attr_internal :foo }
assert !@instance.instance_variables.include?('@_foo')
assert_nothing_raised { assert_equal 1, @instance.foo = 1 }
assert_equal 1, @instance.instance_variable_get('@_foo')
assert_nothing_raised { assert_equal 1, @instance.foo }
end
def test_attr_internal_naming_format
assert_equal '@_%s', @target.attr_internal_naming_format
assert_nothing_raised { @target.attr_internal_naming_format = '@abc%sdef' }
@target.attr_internal :foo
assert !@instance.instance_variables.include?('@_foo')
assert !@instance.instance_variables.include?('@abcfoodef')
assert_nothing_raised { @instance.foo = 1 }
assert !@instance.instance_variables.include?('@_foo')
assert @instance.instance_variables.include?('@abcfoodef')
ensure
@target.attr_internal_naming_format = '@_%s'
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册