在Ruby中,是否有一种方法可以做到
class Foo
attr_reader :var_name :reader_name #This won't work, of course
def initialize
@var_name = 0
end
end
# stuff here ....
def my_method
foo = Foo.new
assert_equal 0,foo.reader_name
end
换句话说,是否存在一种标准方法来为使用不同于变量名称的变量创建访问方法?(当然除了手工编码之外)
您可以使用alias_method
:
class Foo
attr_reader :var_name
alias_method :reader_name, :var_name
def initialize
@var_name = 0
end
end
由attr_reader
构建的var_name
方法仍然可用。您可以使用remove_method
来摆脱var_name
方法,如果你真的想(但要确保你得到的一切都在正确的顺序):
class Foo
attr_reader :var_name
alias_method :reader_name, :var_name
remove_method :var_name
def initialize
@var_name = 0
end
end
如果你真的想,你可以monkey patch一个attr_reader_as
方法到Module:
class Module
def attr_reader_as(attr_name, alias_name)
attr_reader attr_name
alias_method alias_name, attr_name
remove_method attr_name
end
end
class Foo
attr_reader_as :var_name, :reader_name
def initialize
@var_name = 0
end
end
一个更好的attr_reader_as
将采用散列(例如{ var_name: :reader_name, var_name: :reader_name2}
),但我将把它留给读者作为练习。
你不能传递任何选项给attr_reader
这是手工编码吗?
class Foo
def initialize
@var_name = 0
end
def reader_name; @var_name; end
end
首先,我的口头禅是:一个优秀的程序员能很好地配合他的队友。遵循惯例就是让别人开心。
你想要的似乎不符合常规,正如@edgerunner所说,这是不好的做法(阅读:我会打你)。我想说的是,三思而后行,我不知道你的用例,它可能证明是有效的……无论如何,复活节期间应该允许一点乐趣,所以我练习了一些元编程并玩了Mixins。
class Foo
include MyAttrReader
my_attr_reader :var_name, :reader_name
def initialize
@var_name = 0
end
end
很干净。模块完成了这个任务(确保在类之前加载这个模块)
module MyAttrReader
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def my_attr_reader(attribute, read_attribute)
define_method "#{read_attribute}" do
instance_variable_get "@#{attribute}"
end
end
end
end
irb测试
ruby-1.9.2-p180 :001 > load 'my_attr_reader.rb'
=> true
ruby-1.9.2-p180 :002 > load 'foo.rb'
=> true
ruby-1.9.2-p180 :003 > f = Foo.new
=> #<Foo:0x00000100979658 @var_name=0>
ruby-1.9.2-p180 :004 > f.reader_name
=> 0
ruby-1.9.2-p180 :005 > f.var_name
NoMethodError: undefined method `var_name' for #<Foo:0x00000100979658 @var_name=0>
我希望你看到这对其他人来说是多么不直观。您可以重写to_s方法来显示如何访问@var_name,但我不会那样做…或者也定义var_name方法(两个getter方法)。坚持惯例。不管怎样,我玩得很开心,祝你好运!