class Jets::Klass
is available but the path info is now.
for the CloudFormation child stack generation there the registered task info
The from_task method takes a Jets::Lambda::Task as an argument and is useful
Jets::Klass.from_task(task)
Jets::Klass.from_path(“app/shared/functions/whatever.rb”)
Jets::Klass.from_path(“app/functions/hello_function.rb”)
Jets::Klass.from_path(“app/functions/hello.rb”)
Jets::Klass.from_path(“app/jobs/hard_job.rb”)
Jets::Klass.from_path(“app/controllers/posts_controller.rb”)
Examples:
classes like functions are loaded via Object.const_set.
and jobs are loaded via autoloading with .constantize. Anonymously defined
class loading quirk. Classes that are not anonymously defined like controllers
app/functions in a consistent way without having to worry about the anonymous
Jets::Klass provides a way to load app classes in app/controllers, app/jobs,
go through standard autoloading.
Class.new. Anonymous classes cannot be loaded via .constantize and
But app/functions files are anonymous ruby classes created with
Loading a class can usually be loaded via .constantize.
def class_name(path)
def class_name(path) if path.include?("/shared/") path.sub(%r{.*app/shared/(.*?)/},'').sub(/\.rb$/,'').camelize else path.sub(%r{.*app/(.*?)/},'').sub(/\.rb$/,'').camelize end end
def from_path(path)
from_path allows us to load any app classes in consistent way for
def from_path(path) class_name = class_name(path) if path.include?("/functions/") # simple function class_name = load_anonymous_class(class_name, path) class_name.constantize # removed :: for anonymous classes else class_name.constantize # autoload end end
def from_task(task)
def from_task(task) class_name = task.class_name filename = class_name.underscore # Examples of filename: posts_controller, hard_job, security_rule, main_authorizer # hello_function, hello type = filename.split('_').last type = "function" unless APP_TYPES.include?(type) path = "app/#{type.pluralize}/#{filename}.rb" from_path(path) end
def load_anonymous_class(class_name, path)
def load_anonymous_class(class_name, path) parent_mod = modularize(class_name) constructor = Jets::Lambda::FunctionConstructor.new(path) # Dont load anonyomous class more than once to avoid these warnings: # warning: already initialized constant Hello # warning: previous definition of Hello was here unless @@loaded_anonymous_classes.include?(class_name) # use class_name as the variable name for prettier class name. leaf_class_name = class_name.split('::').last parent_mod.const_set(leaf_class_name, constructor.build) @@loaded_anonymous_classes << class_name end class_name end
def modularize(class_name)
parent_mod = modularize("Foo::Bar::Test")
Also returns the parent module, so we can use it to do a const_set if needed. IE:
=> Foo::Bar # is a now defined as a module if it wasnt before
modularize("Foo::Bar::Test")
Ensures the parent namespace modules are defined. Example:
def modularize(class_name) leaves = [] mods = class_name.split('::')[0..-2] # drop the last word # puts "mods: #{mods}" return Object if mods.empty? leaves = [] mods.each do |leaf_mod| leaves += [leaf_mod] namespace = leaves.join('::') previous_namespace = leaves[0..-2].join('::') previous_namespace = "Object" if previous_namespace.empty? previous_namespace = previous_namespace.constantize previous_namespace.const_set(leaf_mod, Module.new) unless Object.const_defined?(namespace) end mods.join('::').constantize end