2011-07-19 28 views
1

请帮助我。在很多类中使用相同的一组属性

我需要在许多类中使用相同的一组属性。我建议创建具有预定义属性的模块并在每个类中扩展此模块

module Basic 
@a=10 
end 

class Use 
extend Basic 
def self.sh 
    @a 
end 
end 

puts Use.sh 

但输出为空。这似乎是我错过了一些东西。

也许有更好的方法来做到这一点?

您的想法?

回答

1

这是all about the self

module Basic 
    @a=10 
end 

self评估为基本。你想让它当后者被扩展,以评估Use

module Basic 
    # self = Basic, but methods defined for instances 
    class << self 
    # self = Basic's eigenclass 
    def extended(base) 
     base.class_eval do 
     # self = base due to class_eval 
     @a=10 
     end 
    end 
    end 
end 

class Use 
    # self = Use, but methods defined for instances 
    extend BasiC# base = Use in the above 
    class << self 
    # self = Use's eigenclass 
    def sh 
     @a 
    end 
    end 
end 

Use.sh # 10 
+0

感谢您的帮助,只有一个问题,我无法弄清楚'扩展(基础)'实际上是什么意思。可以给我一个链接?谢谢! – com

+0

[extended()](http://www.ruby-doc.org/core/classes/Module.html#M000459)有点像[included()](http://www.ruby-doc.org /core/classes/Module.html#M000458):这是一个模块方法,当你使用'extend Basic'时(它会调用'Basic.extend(Use)')。 'included()'当你使用'include Basic'时踢。 –

0

什么你所描述的是Flyweight设计模式。虽然有些人认为这是在红宝石(http://designpatternsinruby.com/section02/flyweight.html)很少使用,其他人提供一个实现(http://www.scribd.com/doc/396559/gof-patterns-in-ruby第14页)

就个人而言,我会做的就是把所有这些属性为YAML文件,然后分析他们要么成为一个全球性变量:

ATTRIBUTES = YAML.load_file(File.expand_path( 'attributes.yml',File.dirname(FILE))

或一个类的方法(带有缓存这里,假设你不会变化yml文件,而应用程序正在运行,并需要新的值)。我建议在这里使用ActiveSupport::Concern,因为它比它更容易阅读传统的混合类方法:

module Basic 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def attributes_file 
     File.expand_path('attributes.yml', File.dirname(__FILE__)) 
    def attributes 
     @attributes ||= YAML.load_file(attributes_file) 
     @attributes 
    end 
    end 

    module InstanceMethods 
    # define any here that you need, like: 
    def attributes 
     self.class.attributes 
    end 
    end 
end 

您可以为每个属性定义方法,或者依赖对属性哈希进行索引。你也可以想象一下,定义method_missing来检查一个属性是否存在这个名字,这样你就不需要继续添加方法,因为你想向共享配置添加更多的属性。

+0

如果你希望改变这些值,并在类之间共享更新后的值,那么Singleton可能是最好的方法。 –

相关问题