代码之家  ›  专栏  ›  技术社区  ›  Will

如何动态更新实例数组以保存实例化时的动态方法列表?

  •  0
  • Will  · 技术社区  · 15 年前

    我的代码看起来像这样

      def xml_attr_reader(*args)
        xml_list = ""
        args.each do |arg|
          string_val = "def #{arg}; " +
                       "   xml_mapping.#{arg}; " +
                       "end; "
          self.class_eval string_val
          xml_hash = xml_list + "'#{arg}',"
        end
    
        self.class_eval "@xml_attributes = [] if @xml_attributes.nil?;" +
                        "@xml_attributes = @xml_attributes + [#{xml_list}];" +
                        "puts 'xml_attrs = ' + @xml_attributes.to_s;" +
                        "def xml_attributes;" +
                        "  puts 'xml_attrs = ' + @xml_attributes.to_s;" +
                        "  @xml_attributes;" +
                        "end"
      end
    

    因此,除了调用实例上的xml\u属性时,其他所有操作都正常工作,它返回null(并输出“xml\u attrs=”)。

    而在定义之前的put实际上会打印出正确的数组(当我实例化实例时)


    kandadaboggu 下面的解决方案有效。我真的没有充分解释我的问题,虽然这里有更多的信息。我想在扩展XmlConfig的类中调用xml\u attr\u reader。基本上我希望它的工作方式与活动记录的attr\u reader相同。

    神田博古

    class XmlConfig
      def xml_attr_reader(*args)
        args.each do |arg|
          class_eval(<<-RUBY, __FILE__, __LINE__)
            def #{arg}
              xml_mapping.#{arg}
            end
          RUBY
        end
        unless respond_to?(:xml_attributes)
          class_eval(<<-RUBY, __FILE__, __LINE__)
            attr_accessor :xml_attributes
          RUBY
        end
        (self.xml_attributes ||=[]).concat(args)
      end
    end
    

    config = XmlConfig.new
    config.xml_attr_reader("age", "name")
    config.age #=> age
    config.name #=> name
    config.xml_attributes #=> ["age", "name" ]
    
    config.xml_attr_reader("city")
    config.city #=> city
    config.xml_attributes #=> ["age", "name", "city"]
    

    我真正想要的是这个(在我的版本中,XmlConfig是一个模块,而不是一个类)

    class Event < ActiveWhatever
      extend XmlConfig
      xml_attr_reader :age, :name
      xml_attr_reader :email, :location
    end
    
    
    class PrivateEvent < Event
      xml_attr_reader :owner, :password
    end
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   Harish Shetty    15 年前

    这是你修正后问题的解决办法。

       module XmlConfig
        def self.included(base)
          base.extend ClassMethods
          base.class_inheritable_array(:xml_attributes)
          base.xml_attributes = []
        end
    
        module ClassMethods    
          def xml_attr_reader(*args)
            args.each do |arg|
              self.class_eval(<<-RUBY, __FILE__, __LINE__)
                def #{arg}
                  xml_mapping.#{arg}
                end
              RUBY
            end
            self.xml_attributes = args
          end
        end
      end
    

    现在你可以了 include 任何类中的模块。

      class Event < ActiveWhatever
        include XmlConfig
        xml_attr_reader :age, :name
        xml_attr_reader :email, :location
      end
    
    
      class PrivateEvent < Event
        xml_attr_reader :owner, :password
      end
    

    Event.xml_attributes        # ->[:age, :name, :email, :location]
    PrivateEvent.xml_attributes # ->[:age, :name, :email, :location, 
                                #                 :owner, :password]
    
    e= Event.new(...)
    e.age     # -> 27
    pe= PrivateEvent.new(...)
    pe.owner  # -> Will
    
        2
  •  1
  •   Harish Shetty    15 年前

    class XmlConfig
      def xml_attr_reader(*args)
        args.each do |arg|
          class_eval(<<-RUBY, __FILE__, __LINE__)
            def #{arg}
              xml_mapping.#{arg}
            end
          RUBY
        end
        unless respond_to?(:xml_attributes)
          class_eval(<<-RUBY, __FILE__, __LINE__)
            attr_accessor :xml_attributes
          RUBY
        end
        (self.xml_attributes ||=[]).concat(args)
      end
    end
    

    现在您可以拨打以下电话:

    config = XmlConfig.new
    config.xml_attr_reader("age", "name")
    config.age #=> age
    config.name #=> name
    config.xml_attributes #=> ["age", "name" ]
    
    config.xml_attr_reader("city")
    config.city #=> city
    config.xml_attributes #=> ["age", "name", "city"]
    

    注: 所有的方法都是实例方法。