class Atomy::Module

this is here so it’s more likely to be filtered out of caller checks

(e.g. sinatra/base)

Attributes

exported_modules[R]
Module

Modules users of this module should automatically use.

file[R]
Symbol

Absolute path to the file the module was loaded from.

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/atomy/module.rb, line 20
def initialize
  extend self

  @exported_modules = []

  # easy accessor for the current module via LexicalScope lookup
  const_set(:Self, self)

  super
end

Public Instance Methods

compile(gen, node) click to toggle source
# File lib/atomy/module.rb, line 35
def compile(gen, node)
  gen.set_line(node.line) if node.respond_to?(:line) && node.line

  expanded = node
  while expanded.is_a?(Atomy::Grammar::AST::Node)
    expanded = expand(expanded)
  end

  expanded.bytecode(gen, self)
rescue
  puts "when compiling: #{node}"
  raise
end
compile_context() click to toggle source
# File lib/atomy/module.rb, line 107
def compile_context
  return @compile_context if @compile_context

  scope = Rubinius::LexicalScope.new(
    self,
    Rubinius::LexicalScope.new(Object))

  meth = proc {}.block.compiled_code
  meth.metadata = nil
  meth.name = :__script__
  meth.scope = scope

  variables =
    Rubinius::VariableScope.synthesize(
      meth, self, nil, self, nil, Rubinius::Tuple.new(0))

  if @file
    script = meth.create_script
    script.file_path = @file.to_s
    script.data_path = File.expand_path(@file.to_s)
    script.make_main!

    scope.script = script
  end

  @compile_context = Binding.setup(variables, meth, scope)
end
evaluate(node, binding = nil) click to toggle source
# File lib/atomy/module.rb, line 49
def evaluate(node, binding = nil)
  binding ||=
    Binding.setup(
      Rubinius::VariableScope.of_sender,
      Rubinius::CompiledCode.of_sender,
      Rubinius::LexicalScope.of_sender,
      self)

  code = Atomy::Compiler.compile(
    node,
    self,
    Atomy::EvalLocalState.new(binding.variables))

  code.add_metadata :for_eval, true

  block = Atomy::Compiler.construct_block(code, binding)
  block.call
end
expand(node) click to toggle source

Node -> (Node | Code)

# File lib/atomy/module.rb, line 98
def expand(node)
  raise UnknownCode.new(node)
end
export(*modules) click to toggle source
# File lib/atomy/module.rb, line 31
def export(*modules)
  @exported_modules.concat(modules)
end
file=(file) click to toggle source
# File lib/atomy/module.rb, line 12
def file=(file)
  @file = file
  Rubinius::Type.set_module_name(self, File.basename(file.to_s).to_sym, Object)
end
inspect() click to toggle source
Calls superclass method
# File lib/atomy/module.rb, line 76
def inspect
  if @file
    super.sub(/>$/, " #{@file}>")
  else
    super
  end
end
load(path) click to toggle source
# File lib/atomy/module.rb, line 72
def load(path)
  Atomy::CodeLoader.load(path)
end
pattern(node) click to toggle source

Node -> Code::Pattern

# File lib/atomy/module.rb, line 103
def pattern(node)
  raise UnknownPattern.new(node)
end
require(path) click to toggle source
# File lib/atomy/module.rb, line 68
def require(path)
  Atomy::CodeLoader.require(path)
end
use(mod) click to toggle source
# File lib/atomy/module.rb, line 84
def use(mod)
  extend mod
  include mod

  if mod.is_a?(self.class)
    mod.exported_modules.each do |m|
      use(m)
    end
  end

  mod
end

Private Instance Methods

extend(mod) click to toggle source

atomy module semantics are defined via ‘extend self’, but we have to make sure that later extends are added after self

this ensures that modules a module use don’t take priority over the module’s own methods

Calls superclass method
# File lib/atomy/module.rb, line 142
def extend(mod)
  return super if mod == self

  mod.include_into(singleton_class.direct_superclass)
end