"Bezel"  Bezel

In Files

Information

Class Index [+]

Quicksearch
[Validate]
Generated with RDazzle RedFish v1.0.1

Bezel

The idea of Bezel is to overcome the limitations of using different versions of the same package in the same Ruby proccess.

It works like this. Let’s say I wrote a library called TomsLib. Now I want to use TomsLib in my new fancy app, FancyApp. In my FancyApp namespace I have to create a reference to TomsLib.

module FancyApp
  TomsLib = lib('tomslib', '1.5')
  ...

Now I have access to TomsLib, but it is localized to my application. If Jane comes along and wants to use a different version of TomsLib but also utilizes my FancyApp, she could do so:

module JanesProgram
  TomsLib  = lib('tomslib', '1.0')
  FancyApp = lib('fancyapp')  # use newest available
  ...

How does this work? When you call lib(), Bezel looks for the package in the current gem paths (and, in the future, Roll ledger) then it reads the primary package file (eg. tomslib.rb) fro the package and evals it into an anonymous module.

This has a some important effects on how you write your Ruby programs:

  1. Any reference to core/standard libraries must be referenced via

    prefix (eg. ::Enumerable).

  2. Core extensions are not version controlled. So avoid them when possible, or depend on highly stable standardized bases such as Facets and ActiveSupport.

  3. Since Bezel is a completely different alternative to Ruby’s normal load system, your program will require Bezel be installed by your users.

Despite these necessary practices for its use, Bezel is highly advantageous to the developers and end-users alike in that it puts an end to the dreaded Dependency Hell.

TODO: Consider how best to support alternate loadpaths beyond ‘lib/’.

Constants

TABLE

Cache of loaded modules. This speeds things up if two libraries load the same third library.

STACK

Load stack keeps track of what modules are in the process of being loaded.

Public Class Methods

find(name, version=nil) click to toggle source
# File lib/bezel.rb, line 123
def self.find(name, version=nil)
  path = nil
  path ||= gem_find(name, version)  if defined?(::Gem)
  path ||= roll_find(name, version) if defined?(::Roll)
  path
end
gem_find(name, version) click to toggle source
# File lib/bezel.rb, line 131
def self.gem_find(name, version)
  raise ArgumentError, "version must be explicit" unless version

  basename = "#{name}-#{version}"
  gem_paths.find do |path|
    File.basename(path) == basename
  end
end
gem_paths() click to toggle source
# File lib/bezel.rb, line 141
def self.gem_paths
  @gem_paths ||= (
    Gem.path.map do |dir|
      Dir[File.join(dir, 'gems', '*')]
    end.flatten
  )
end
import(fname) click to toggle source
# File lib/bezel.rb, line 83
def self.import(fname)
  ## lookup most recent Bezel module
  mod = STACK.last
  ## if Bezel module is returned
  if mod
    ## TODO: Hadle loadpath?
    file = File.join(mod.__path__, 'lib', fname)
    ## TODO: Support other extensions, like .rbx and .so?
    file = file + '.rb' unless file[-3,3] == '.rb'
    ## raise load error if file does not exist
    raise LoadError, "no such file to load -- #{file}" unless File.exist?(file)
    ## evaluate script in the context of module
    mod.module_eval(File.read(file), file, 0)
  else ## if no Bezel module is returned
    ## fallback to regular require
    require(fname)
  end
end
lib(name, version=nil) click to toggle source

Load library into a module namespace.

# File lib/bezel.rb, line 57
def self.lib(name, version=nil)
  path = find(name, version)
  ## load error if no gem found
  raise LoadError, "#{name}-#{version} not found" unless path
  ## location of bezel file
  main = File.join(path, 'lib', name + '.bezel')  #TODO:LOADPATH
  ## check cache
  return TABLE[main] if TABLE.key?(main)
  ## load error if no bezel file
  raise LoadError, "#{name}-#{version} has no bezel!" unless File.exist?(main)
  ## read in bezel file
  script = File.read(main)
  # create new Bezel module for file
  mod = new(name, version, path)
  ## put module on STACK
  STACK.push mod
  ## evaluate script in the context of module
  mod.module_eval(script, main, 0)  # r =
  ## pop module off STACK
  STACK.pop
  ## add module to cache, and return module
  TABLE[main] = mod
  # if Module === r ? r : mod
end
new(name, version, path) click to toggle source

Construct new Bezel module.

# File lib/bezel.rb, line 155
def initialize(name, version, path)
  @__name__    = name
  @__version__ = version
  @__path__    = path
  super()
end
roll_find(name,version=nil) click to toggle source

TODO: Add Roll finder.

# File lib/bezel.rb, line 150
def self.roll_find(name,version=nil)
  return nil
end

Public Instance Methods

__name__() click to toggle source

Name of library.

# File lib/bezel.rb, line 163
def __name__
  @__name__
end
__path__() click to toggle source

Path to library.

# File lib/bezel.rb, line 173
def __path__
  @__path__
end
__version__() click to toggle source

Version of library.

# File lib/bezel.rb, line 168
def __version__
  @__version__
end

Disabled; run with --debug to generate this.