12. Packages, Libraries, and Modules

Introduction

# class and module names need to have the first letter capitalized
module Alpha
    NAME = 'first'
end
module Omega
    NAME = 'last'
end
puts "Alpha is #{Alpha::NAME}, Omega is #{Omega::NAME}"

# ruby doesn't differentiate beteen compile-time and run-time
require 'getoptlong.rb'
require 'getoptlong'     # assumes the .rb
require 'cards/poker.rb'
require 'cards/poker'    # assumes the .rb
load    'cards/poker'    # require only loads the file once

module Cards
    module Poker
        @card_deck = Array.new # or @card_deck = []
        def shuffle
        end
    end
end

Defining a Module's Interface

# a module exports all of its functions
module Your_Module
    def self.function
        # this would be called as Your_Module.function
    end
    
    def Your_Module.another
        # this is the same as above, but more specific
    end
end

Trapping Errors in require or use

begin
    require 'nonexistent'
rescue LoadError
    puts "Couldn't load #{$!}"  # $! contains the last error string
end

Delaying use Until Run Time

Making Variables Private to a Module

# module variables are private unless access functions are defined
module Alpha
    @aa = 10
    @bb = 11
    
    def self.put_aa
        puts @aa
    end
    
    def self.bb=(val)
        @bb = val
    end
end

Alpha.bb = 12
# Alpha.aa = 10 # error, no aa=method

Determining the Caller's Package

# caller provides a backtrace of the call stack
module MyModule
    def find_caller
        caller
    end

    def find_caller2(i)
        caller(i) # an argument limits the size of the stack returned
    end
end

Automating Module Clean-Up

BEGIN {
    $logfile = '/tmp/mylog' unless defined? $logfile
    $LF = File.open($logfile, 'a')
}

module Logger
    def self.logmsg(msg)
        $LF.puts msg
    end

    logmsg('startup')
end

END {
    Logger::logmsg('shutdown')
    $LF.close
}

Keeping Your Own Module Directory

#-----------------------------
# results may be different on your system
# % ruby -e "$LOAD_PATH.each_index { |i| printf("%d %s\n", i, $LOAD_PATH[i] }
#0 /usr/local/lib/site_ruby/1.6
#1 /usr/local/lib/site_ruby/1.6/i386-linux
#2 /usr/local/lib/site_ruby/
#3 /usr/lib/ruby/1.6
#4 /usr/lib/ruby/1.6/i136-linux
#5 .
#-----------------------------
# syntax for sh, bash, ksh, or zsh
#$ export RUBYLIB=$HOME/rubylib

# syntax for csh or tcsh
# % setenv RUBYLIB ~/rubylib
#-----------------------------
$LOAD_PATH.unshift "/projects/spectre/lib";

Preparing a Module for Distribution

# equivalents in ruby are mkmf, SWIG, or Ruby/DL depending on usage

Speeding Module Loading with SelfLoader

# no equivalent in ruby

Speeding Up Module Loading with Autoloader

# no equivalent in ruby

Overriding Built-In Functions

module FineTime
    def self.time
        # to be defined later
    end
end


module FineTime
    def self.time
        "its a fine time"
    end
end

puts FineTime.time #=> "its a fine time"

Reporting Errors and Warnings Like Built-Ins

def even_only(n)
    raise "#{n} is not even" if (n & 1) != 0  # one way to test
    # ...
end
def even_only(n)
    $stderr.puts "#{n} is not even" if (n & 1) != 0
    # ...
end

Referring to Packages Indirectly

Using h2ph to Translate C #include Files

Using h2xs to Make a Module with C Code

Documenting Your Module with Pod

Building and Installing a CPAN Module

# The library archive for ruby is called Ruby Application archive,
# or shorter RAA, and can be found at http://raa.ruby-lang.org.
# A typical library is installed like this:
# % gunzip some-module-4.54.tar.gz
# % tar xf some-module-4.54.tar
# % cd some-module-4.54.tar
# % ruby install.rb config
# % ruby install.rb setup
# get superuser previleges here if needed for next step
# % ruby install.rb install

# Some modules use a different process,
# you should find details in the documentation
# Here is an example of such a different process
# % ruby extconf.rb
# % make
# % make install

# If you want the module installed in your own directory:
# For ruby version specific libraries
# % ruby install.rb config --site-ruby=~/lib
# For version independent libraries
# % ruby install.rb config --site-ruby-common=~/lib

# Information about possible options for config
# % ruby install.rb --help

# If you have your own complete distribution
# % ruby install.rb --prefix=path=~/ruby-private

Example: Module Template

Program: Finding Versions and Descriptions of Installed Modules