Get all classes defined in module ruby - ruby

Is it possible to know all the classes defined inside a module in ruby.
module A
class Klass
end
class Klass1
end
end
Is there any ruby introspection method to get all the classes defined in module A?

Here is one way
module A
class Klass
end
X = 10
module B;end
end
# Just to list the class(s) defined inside A
A.constants.select { |k| A.const_get(k).instance_of? Class } # => [:Klass]
Nice post to do the same in recursively.

Related

How to call a method defined in one module from another module when they are both included in a class in Ruby?

module A
def before
puts :before
end
end
module B
before
end
class Test
include A
include B
end
So, the goal is to call before as module B is parsed, without using extend A within module B.
Ruby 2.5.1
When you include a module, that takes the instance methods of the module and imports them as instance methods. However, the way you call the before method here, would only work if it was a class method.
If you want B to import before as a class method, you can do so with extend:
module B
extend A
before
end
Without this additional extend, you could call before from B only in instance method scope, and only if the method on B was called by Test:
module A
def before
puts :before
end
end
module B
def call_before
before
end
end
class Test
include A
include B
def do_thing
call_before
end
end
Test.new.do_thing # => before

How could I access global method from class method both are in the same module

I got this error
NoMethodError (undefined method `get_routes' for
How could I access get_routes from Sample.run
module FlightUtil
extend ActiveSupport::Concern
def get_routes(from="TAIPEI", to="OSAKA")
~~~
end
class Sample
def run
get_routes("A", "B")
end
end
end
You need to include the module FlightUtil in the Sample class.
module FlightUtil
extend ActiveSupport::Concern
def get_routes(from="TAIPEI", to="OSAKA")
~~~
end
class Sample
include FlightUtil
def run
get_routes("A", "B")
end
end
end
A Module is a collection of methods and constants. Classes nested inside of modules are used to namespace the classes. You have to include a module in order to access the module's contents (methods or constants).

Ruby and module inheritance

This should be an easy one for a ruby dev. I'm playing around with a gem and I need help with inheriting module variables. Code should speak better than me:
module SomeModule
extend ActiveSupport::Concern
attr_accessor :bbonified
class Railtie < Rails::Railtie
initializer "some_module.study" do
Rails.application.eager_load!
# => I WANT TO ACCESS HERE
puts #bbonified
end
end
module ClassMethods
def bbonify(*columns)
# => WHAT I DEFINE HERE
#bbonified = columns
end
end
end
ActiveRecord::Base.send(:include, SomeModule)
You're not going to be able to access #bbonified directly, that's a local variable in the class that imports this module.
You need to define a separate accessor method to retrieve it:
module ClassMethods
def bbonified
#bbonified
end
end
Then later you need to refer to this somehow, but as you're just talking about a module it will depend on what class has been extended.
Rails.application.eager_load!
SomeClass.bbonified

Modules in Ruby

Please explain why self is used in def self.included (klass) below.
module A
def self.included(klass)
puts "A -> #{klass}"
puts A
puts self
end
end
class X
include A
end
By writing def self.included you are defining a method that is part of the singleton class of module A. In general, singleton methods can only be called by doing A.included() but this singleton method has a special name included that causes the Ruby interpreter to call when the module gets included in to a class.
A normal method in a module (defined with def foo) can only be called if the module gets included in to something else.
This is how you declare a module method that can be called directly. Normally methods defined within a module are only usable if another class or module includes them, like class X in this example.
module Example
def self.can_be_called
true
end
def must_be_included
true
end
end
In this case you will see these results:
Example.can_be_called
# => true
Example.must_be_included
# => NoMethodError: undefined method `must_be_included' for Example:Module
The self declared methods are not merged in to the classes or modules that include it, though. They are special-purpose that way.

Ruby metaprogramming question

When I call self.class.instance_variable_set("#var", ...) from inside a class method, where is that variable actually stored? Is it on the class itself? On the instance of that class? I can't seem to find it with any of the following:
e = Example.new
e.instance_variables
e.class.class_variables
I even tried using the (class << self; self; end) trick but I can't find anything (http://ruby-metaprogramming.rubylearning.com/html/seeingMetaclassesClearly.html).
Here is the code snippet (which works as I need) but I'm not sure why it works :)
module HandyModule
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def use_template(template_name)
self.class.instance_variable_set("#_template", template_name)
end
def build(attributes = {})
template_name = self.class.instance_variable_get("#_template")
# do stuff with the template
end
end
end
class Example
include HandyModule
use_template :contact_form
end
Essentially I can include this handy module, and then I have a class method called use_template with which I can specify which template to be used by my build method.
When you call use_template inside the class definition, the self is the class Example. When you call self.class, it is Example.class, or Class. You define the instance variable to the class of the classes.
class Class
p #_template
end
# prints :contact_form
You probably should use just self instead of self.class.

Resources