class Myco::CodeLoader

Attributes

emit_rb[RW]
emit_rbc[RW]
precedence[RW]

Public Class Methods

load(path, load_paths, kwargs={}) click to toggle source

Load from the given path and load_paths and call under the given ConstantScope, VariableScope, and receiver. If cscope or vscope or receiver are nil, they are pulled from the given call_depth, corresponding to one of the calling frames.

TODO: fix rubinius JIT issue and use “call_depth:1, **kwargs” here

# File lib/myco/code_loader.rb, line 89
def self.load path, load_paths, kwargs={}
  kwargs[:call_depth] ||= 1
  begin
    loader = loader_for_file(path, load_paths)
    loader.bind_to(kwargs.merge(call_depth: kwargs[:call_depth] + 1))
    loader.compile
    loader.emit_rb!  if self.emit_rb
    loader.emit_rbc! if self.emit_rbc
    loader.load
  rescue Rubinius::InvalidRBC
    retry
  end
end
loader_for(type, *args) click to toggle source

Return a loader of the given type with the given arguments

# File lib/myco/code_loader.rb, line 74
def self.loader_for type, *args
  case type
  when :myco; MycoLoader.new(*args)
  when :rbc;  BytecodeLoader.new(*args)
  when :rb;   RubyLoader.new(*args)
  else;       raise NotImplementedError
  end
end
loader_for_file(path, load_paths=[]) click to toggle source

Select a loader and file path for the given path, considering the currently selected order of precedence for file types.

# File lib/myco/code_loader.rb, line 35
def self.loader_for_file path, load_paths=[]
  use_path = resolve_file(path, load_paths)
  
  # TODO: This logic could be refactored to look cleaner
  if use_path && defined? Myco::ToolSet
    # Try to find an implementation with higher precedence than :myco
    # With a file that has been modified at least as recently as
    # the resolved file in use_path.
    ref_mtime = File.mtime(use_path)
    precedence.each { |type|
      begin
        if type==:myco
          return loader_for(type, use_path)
        else
          alt_path = use_path + ".#{type}"
          if File.file?(alt_path) && (File.mtime(alt_path) >= ref_mtime)
            return loader_for(type, alt_path)
          end
        end
      rescue NotImplementedError # Skip loader if not implemented
      end
    }
  else
    # Try to find any implementation other than :myco, in precedence order.
    precedence.each { |type|
      if type != :myco
        alt_path = resolve_file(path + ".#{type}", load_paths)
        if alt_path && File.file?(alt_path)
          return loader_for(type, alt_path)
        end
      end
    }
  end
  
  raise ArgumentError, "Couldn't resolve file: #{path.inspect} \n" \
                       "in load_paths: #{load_paths.inspect}" \
end
resolve_file(path, load_paths=[]) click to toggle source

Try to resolve the given file path in the current working directory or in the given load paths.

# File lib/myco/code_loader.rb, line 21
def self.resolve_file path, load_paths=[]
  tmp_path = File.expand_path(path)
  use_path = File.file?(tmp_path) && tmp_path
  load_paths.each { |load_path|
    break if use_path
    tmp_path = File.expand_path(path, load_path)
    use_path = File.file?(tmp_path) && tmp_path
  }
  
  use_path
end