Creating a class dynamically

后端 未结 2 1506
南方客
南方客 2020-12-29 07:43

I\'m trying to create a new class, without knowing the name of the class until it\'s supposed to på created.

Something like this;

    variable = \"V         


        
相关标签:
2条回答
  • 2020-12-29 08:04

    Your code would look something akin to this:

    variable = "SomeClassName"
    klass = Class.new(ParentClass)
    # ...maybe evaluate some code in the context of the new, anonymous class
    klass.class_eval {  }
    # ...or define some methods
    klass.send(:title, :Person)
    klass.send(:attribute, :name, String)
    # Finally, name that class!
    ParentClass.send(:const_set, variable, klass)
    

    ...or you could just use eval:

    eval <<DYNAMIC
      class #{name}
        title :Person
        attribute :name, String
        # ...or substitute other stuff in here.
      end
    DYNAMIC
    
    0 讨论(0)
  • 2020-12-29 08:18

    A class gains its name when it is assigned to a constant. So It's easy to do in a generic fashion with const_set.

    For example, let's say you want to use Struct to build a class with some attributes, you can:

    name = "Person"
    attributes = [:name, :age]
    
    klass = Object.const_set name, Struct.new(*attributes)
    # Now use klass or Person or const_get(name) to refer to your class:
    Person.new("John Doe", 42) # => #<struct Person name="John Doe", age=42>
    

    To inherit from another class, replace the Struct.new by Class.new(MyBaseClass), say:

    class MyBaseClass; end
    
    klass = Class.new(MyBaseClass) do
      ATTRIBUTES = attributes
      attr_accessor *ATTRIBUTES
      def initialize(*args)
        raise ArgumentError, "Too many arguments" if args.size > ATTRIBUTES.size
        ATTRIBUTES.zip(args) do |attr, val|
          send "#{attr}=", val
        end
      end
    end
    Object.const_set name, klass
    Person.new("John Doe", 42) # => #<Person:0x007f934a975830 @name="John Doe", @age=42> 
    
    0 讨论(0)
提交回复
热议问题