Class: Jets::Klass

Inherits:
Object
  • Object
show all
Defined in:
lib/jets/klass.rb

Overview

Loading a class can usually be loaded via .constantize. But app/functions files are anonymous ruby classes created with Class.new. Anonymous classes cannot be loaded via .constantize and go through standard autoloading.

Jets::Klass provides a way to load app classes in app/controllers, app/jobs, app/functions in a consistent way without having to worry about the anonymous class loading quirk. Classes that are not anonymously defined like controllers and jobs are loaded via autoloading with .constantize. Anonymously defined classes like functions are loaded via Object.const_set.

Examples:

Jets::Klass.from_path("app/controllers/posts_controller.rb")
Jets::Klass.from_path("app/jobs/hard_job.rb")
Jets::Klass.from_path("app/functions/hello.rb")
Jets::Klass.from_path("app/functions/hello_function.rb")
Jets::Klass.from_path("app/shared/functions/whatever.rb")

Jets::Klass.from_task(task)

The from_task method takes a Jets::Lambda::Task as an argument and is useful for the CloudFormation child stack generation there the registered task info is available but the path info is now.

Constant Summary collapse

@@loaded_anonymous_classes =
[]

Class Method Summary collapse

Class Method Details

.class_name(path) ⇒ Object

app/controllers/posts_controller.rb => PostsController



40
41
42
43
44
45
46
# File 'lib/jets/klass.rb', line 40

def class_name(path)
  if path.include?("/shared/")
    path.sub(%r{.*app/shared/(.*?)/},'').sub(/\.rb$/,'').classify
  else
    path.sub(%r{.*app/(.*?)/},'').sub(/\.rb$/,'').classify
  end
end

.from_path(path) ⇒ Object

from_path allows us to load any app classes in consistent way for app/controllers, app/jobs, and app/functions.



29
30
31
32
33
34
35
36
37
# File 'lib/jets/klass.rb', line 29

def from_path(path)
  class_name = class_name(path)

  if path.include?("/functions/") # simple function
    load_anonymous_class(class_name, path)
  end

  class_name.constantize # autoload or nothing if load_anonymous_class called
end

.from_task(task) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/jets/klass.rb', line 48

def from_task(task)
  class_name = task.class_name
  filename = class_name.underscore

  # Examples of filename: posts_controller, hard_job, security_rule,
  #   hello_function, hello
  valid_types = %w[controller job rule]
  type = filename.split('_').last
  type = "function" unless valid_types.include?(type)

  path = "app/#{type.pluralize}/#{filename}.rb"
  from_path(path)
end

.load_anonymous_class(class_name, path) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/jets/klass.rb', line 63

def load_anonymous_class(class_name, path)
  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.
    Object.const_set(class_name, constructor.build)
    @@loaded_anonymous_classes << class_name
  end
end