Skip to content

Instantly share code, notes, and snippets.

@pkoch

pkoch/README.md

Created Apr 19, 2020
Embed
What would you like to do?
Discover?

In dolphin, we have a place where we list the "registered tempaltes".

      @templates = (templates || [                                                
        Templates::Goodbye1::Definition,                                          
        Templates::Hello1::Definition,                                            
        Templates::Login::Definition,                                             
        Templates::OAuthContinue::Definition,                                     
        Templates::RegistrationConfirmation::Definition,                          
        Templates::VerificationSubmitted::Definition,                             
        Templates::TanCode::Definition,                                           
        Templates::VerificationApproved::Definition,                              
        Templates::VerificationContact::Definition,                               
        Templates::VerificationRejected::Definition,                              
      ]).index_by(&:template_name)  

It's kinda tedious to update this by hand, and we can instead do something like discover(BaseTemplate, roots: [Templates]), but that would require that we turn on eager loading, and I kinda don't wanna do that. No particular reasons, it's just™ going to be yet another kink to babysit.

My fears can be considered unfounded, and you all might have different opinions, hence me checking in.

module ClassNavigator
using (Module.new do # rubocop:disable Lint/ParenthesesAsGroupedExpression
refine Module do
def constants_gotten
constants.map { |m| const_get m }
end
end
end)
def self.global_constants
Kernel.instance_eval { Module.constants_gotten }
end
def self.discover(top_class, roots: nil)
roots = global_constants if roots.nil?
roots.flat_map do |root|
next [root] if root.is_a?(Class) && root < top_class
next [] unless root.is_a?(Module)
discover(top_class, roots: root.constants_gotten)
end
end
end
require "test_helper"
module ClassNavigatorTest
class TargetParent; end
module MA
class A < TargetParent; end
end
module MB
module MBB
class B < TargetParent; end
end
end
end
describe ClassNavigator.method(:discover) do
it do
assert_equal(
[
ClassNavigatorTest::MA::A,
ClassNavigatorTest::MB::MBB::B,
],
topic.call(
ClassNavigatorTest::TargetParent,
roots: [ClassNavigatorTest],
).sort_by(&:name),
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment