开发者

How to load a unknown class in a module?

I have some rb files, all with the same structure:

class RandomName < FooBa开发者_StackOverflow社区r
end

The randomname is a random class name which changes in each rb file but all inherits from Foobar.

how i can load all randomclass from there rb files?


I think there are 2 parts to the solution:

  1. How to dynamically instantiate a class

    a. Using String#constantize from ActiveSupport

    klass = "SomeNamespace::SomeClassName".constantize
    klass.new
    

    b. Use Module#const_get (which doesn't handle namespaces)

    klass = const_get(:SomeClassName)
    klass.new
    
  2. How to detect a class name

    A convention followed widely in ruby is to name the file after the class that it contains, so random_name.rb would contain the RandomName class. If you follow this convention, then you could do something like:

    Dir["/path/to/directory/*.rb"].each do |file| 
      require file 
      file_name = File.basename(file.path, '.rb')
       # using ActiveSupport for camelcase and constantize
      file_name.camelcase.constantize.new 
    end
    

I think you should explain what you are trying to accomplish. The approach you are taking seems unconventional and there may be a much more effective way of reaching your goal without doing all this loading of files and dynamic instantiation of classes with random names.

Remember, just because ruby lets you do something, it doesn't mean it's a good idea to actually do it!


you can define a method called inherited in the FooBar class. look here

class FooBar
  def self.inherited(subclass)
    puts "New subclass: #{subclass}"
  end
end

Every time a subclass is created, you will get it in the callback. Then you can do whatever you want with all those subclasses.


I have a similar requirement, passing a class name in as a string. One trick with require is that it doesn't have to be at the start, so I prefer to only load the class I need.

I used eval because it doesn't have any Rails dependencies (I'm writing pure Ruby code here).

The following relies on convention (that the Class is in a file of the same name), but if you do know the class and file, this approach has the advantage of not requiring every file in a directory and only dynamically loading the one you need at the time you need it.

klass = "classname"

begin

    # Load the file containing the class from same directory I'm executing in
    require_relative klass # Or pass a local directory like "lib/#{klass}"

    # Use eval to convert that string to a Constant (also capitalize it first)
    k = eval(klass.capitalize).new

rescue
    # Do something if the convention fails and class cannot be instantiated.

end

k.foo # Go ahead and start doing things with your new class.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜