module Kernel

Public Class Methods

backtrace_remove_first_occurence_of(e, rx) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 5
def self.backtrace_remove_first_occurence_of(e, rx)
    # Remove the first occurence of eval_dsl_file_content in the backtrace
    backtrace = e.backtrace.dup
    found = false
    backtrace.delete_if do |line|
        break if found
        line =~ rx
        found = true
    end
    raise e, e.message, e.backtrace
end
name() click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 153
def self.name; "" end
new(obj) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 155
def initialize(obj); @main_object = obj end

Public Instance Methods

check_arity(object, arity, strict: nil) click to toggle source

Raises if object can accept calls with exactly arity arguments. object should respond to arity

# File lib/utilrb/kernel/arity.rb, line 4
def check_arity(object, arity, strict: nil)
    if strict.nil?
        if object.respond_to?(:lambda?)
            strict = object.lambda?
        else strict = true
        end
    end

    if strict
        if object.arity >= 0 && object.arity != arity
            raise ArgumentError, "#{object} requests #{object.arity} arguments, but #{arity} was requested"
        elsif -object.arity-1 > arity
            raise ArgumentError, "#{object} requests at least #{object.arity} arguments, but #{arity} was requested"
        end
    end
end
dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 145
def dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code)
    dsl_exec_common(nil, proxied_object, context, full_backtrace, *exceptions, &code)
end
dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 149
def dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code)
    load_dsl_filter_backtrace(file, full_backtrace, *exceptions) do
        sandbox = with_module(*context) do
            Class.new(BasicObject) do
                def self.name; "" end
                attr_accessor :main_object
                def initialize(obj); @main_object = obj end
                def method_missing(*m, &block)
                    main_object.__send__(*m, &block)
                end
            end
        end

        old_constants, new_constants = Kernel.constants, nil

        sandbox = sandbox.new(proxied_object)
        sandbox.with_module(*context) do
            old_constants =
                if respond_to?(:constants)
                    constants
                else  self.class.constants
                end

            instance_eval(&code)

            new_constants =
                if respond_to?(:constants)
                    constants
                else  self.class.constants
                end
        end

        # Check if the user defined new constants by using class K and/or
        # mod Mod
        if !new_constants
            new_constants = Kernel.constants
        end

        new_constants -= old_constants
        new_constants.delete_if { |n| n.to_s == 'WithModuleConstResolutionExtension' }
        if !new_constants.empty?
            msg = "#{new_constants.first} does not exist. You cannot define new constants in this context"
            raise NameError.new(msg, new_constants.first)
        end
        true
    end
end
eval_dsl(text, proxied_object, context, full_backtrace, *exceptions) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 93
def eval_dsl(text, proxied_object, context, full_backtrace, *exceptions)
    eval_dsl_file_content(nil, text, proxied_object, context, full_backtrace, *exceptions)
end
eval_dsl_block(block, proxied_object, context, full_backtrace, *exceptions) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 86
def eval_dsl_block(block, proxied_object, context, full_backtrace, *exceptions)
    load_dsl_filter_backtrace(nil, full_backtrace, *exceptions) do
        proxied_object.with_module(*context, &block)
        true
    end
end
eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block) click to toggle source

Load the given file by eval-ing it in the provided binding. The originality of this method is to translate errors that are detected in the eval'ed code into errors that refer to the provided file

The caller of this method should call it at the end of its definition file, or the translation method may not be robust at all

# File lib/utilrb/kernel/load_dsl_file.rb, line 118
def eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block)
    file = File.expand_path(file)
    if !File.readable?(file)
        raise ArgumentError, "#{file} does not exist"
    end

    file_content = File.read(file)
    eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions, &block)
end
eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 97
    def eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions)
        code = with_module(*context) do
            code =  <<-EOD
            Proc.new { #{file_content} }
            EOD
            if file
                eval code, binding, file, 1
            else
                eval code, binding
            end
        end

        dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code)
    end
filter_options(option, hash) → known, unknown click to toggle source
filter_options(option, array) → known, unknown
filter_options(nil, known_options) → default_options, {}

Partitions an option hash between known arguments and unknown arguments, with default value support. All option keys are converted to symbols for consistency.

The following rules apply:

* if a hash is given, non-nil values are treated as default values.
* an array is equivalent to a hash where all values are 'nil'

See validate_options and filter_and_validate_options

# File lib/utilrb/kernel/options.rb, line 32
def filter_options(options, *user_option_spec)
    options = options.dup
    known_options = Hash.new
    user_option_spec.each do |opt|
        if opt.respond_to?(:to_hash)
            opt.each do |key, value|
                if filter_options_handle_single_entry(known_options, options, key)
                    if !value.nil?
                        known_options[key.to_sym] = value
                    end
                end
            end
        elsif opt.respond_to?(:to_ary)
            opt.each do |key|
                filter_options_handle_single_entry(known_options, options, key)
            end
        else
            filter_options_handle_single_entry(known_options, options, opt)
        end
    end

    return *[known_options, options]
end
filter_options_handle_single_entry(known_options, options, key) click to toggle source
# File lib/utilrb/kernel/options.rb, line 4
def filter_options_handle_single_entry(known_options, options, key)
    key = key.to_sym
    if options.has_key?(key)
        known_options[key] = options.delete(key)
        false
    elsif options.has_key?(key_s = key.to_s)
        known_options[key] = options.delete(key_s)
        false
    else
        true
    end
end
load_dsl_file(file, *args, &block) click to toggle source

Same than eval_dsl_file, but will not load the same file twice

# File lib/utilrb/kernel/load_dsl_file.rb, line 129
def load_dsl_file(file, *args, &block)
    file = File.expand_path(file)
    if $LOADED_FEATURES.include?(file)
        return false
    end

    $LOADED_FEATURES << file
    begin
        eval_dsl_file(file, *args, &block)
    rescue Exception
        $LOADED_FEATURES.delete(file)
        raise
    end
    true
end
load_dsl_filter_backtrace(file, full_backtrace = false, *exceptions) { || ... } click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 17
def load_dsl_filter_backtrace(file, full_backtrace = false, *exceptions)
    # Compute the position of the dsl-loading method that called us, so that
    # we don't touch anything below that while we are filtering the
    # backtrace
    if !full_backtrace
        callers = caller
        our_frame_pos = caller.size
        callers.each do |line|
            if line != /load_dsl_file\.rb/
                our_frame_pos -= 1
            else
                break
            end
        end
    end

    yield

rescue Exception => e
    raise e if full_backtrace
    if exceptions.any? { |e_class| e.kind_of?(e_class) }
        raise e
    end

    backtrace = e.backtrace.dup
    message   = e.message.dup

    # Filter out the message ... it can contain backtrace information as
    # well (!)
    message = message.split("\n").map do |line|
        if line =~ /^.*:\d+(:.*)$/
            backtrace.unshift line
            nil
        else
            line
        end
    end.compact.join("\n")


    if message.empty?
        message = backtrace.shift
        if message =~ /^(\s*[^\s]+:\d+:)\s*(.*)/
            location = $1
            message  = $2
            backtrace.unshift location
        else
            backtrace.unshift message
        end
    end

    filtered_backtrace = backtrace[0, backtrace.size - our_frame_pos].
        map do |line|
            line = line.gsub(/:in `.*dsl.*'/, '')
            if line =~ /load_dsl_file.*(method_missing|send)/
                next
            end

            if line =~ /(load_dsl_file\.rb|with_module\.rb):\d+/
                next
            else
                line
            end
        end.compact


    backtrace = (filtered_backtrace[0, 1] + filtered_backtrace + backtrace[(backtrace.size - our_frame_pos)..-1])
    raise e, message, backtrace
end
method_missing(*m, &block) click to toggle source
# File lib/utilrb/kernel/load_dsl_file.rb, line 156
def method_missing(*m, &block)
    main_object.__send__(*m, &block)
end
normalize_options(options) click to toggle source

Normalizes all keys in the given option hash to symbol and returns the modified hash

# File lib/utilrb/kernel/options.rb, line 58
def normalize_options(options)
    options.to_sym_keys
end
null_enum() click to toggle source

returns always the same null enumerator, to avoid creating objects. It can be used as a seed to inject:

enumerators.inject(null_enum) { |a, b| a + b }.each do |element|
end
# File lib/utilrb/enumerable/null.rb, line 16
def null_enum
    @@null_enumerator ||= NullEnumerator.new.freeze
end
poll(cycle) { || ... } click to toggle source

Yields every cycle seconds

# File lib/utilrb/kernel/poll.rb, line 3
def poll(cycle)
    loop do
        yield
        sleep(cycle)
    end
end
require_dir(filename, exclude = nil) click to toggle source

Require all .rb files in the filename directory

# File lib/utilrb/kernel/require.rb, line 3
def require_dir(filename, exclude = nil)
    dirname = filename.gsub(/.rb$/, '')
    Dir.new(dirname).each do |file|
        next if exclude && exclude === file
        if file =~ /\.rb$/
            require File.join(dirname, file)
        end
    end
end
validate_option(options, name, required, message) { |v| ... } click to toggle source
validate_option(options, name, required, message)

Validates option name in the options hash. If required is true, raises ArgumentError if the option is not present. Otherwise, yields its value to an optional block, which should return if the value is valid, or false otherwise. If the value is invalid, raises ArgumentError with message or a standard message.

# File lib/utilrb/kernel/options.rb, line 90
def validate_option(options, name, required, message = nil)
    if required && !options.has_key?(name)
        raise ArgumentError, "missing required option #{name}"
    elsif options.has_key?(name) && block_given?
        if !yield(options[name])
            raise ArgumentError, (message || "invalid option value #{options[name]} for #{name}")
        end
    end
end
validate_options(options, *known_options) click to toggle source

Validates an option hash, with default value support. See filter_options

In the first form, option_hash should contain keys which are also in known_hash. The non-nil values of known_hash are used as default values. In the second form, known_array is an array of option keys. option_hash keys shall be in known_array. nil is treated as an empty option hash, all keys are converted into symbols.

# File lib/utilrb/kernel/options.rb, line 70
def validate_options(options, *known_options)
    options ||= Hash.new
    opt, unknown = Kernel.filter_options(options.to_hash, *known_options)
    unless unknown.empty?
        not_valid = unknown.keys.map { |m| "'#{m}'" }.join(" ")
        raise ArgumentError, "unknown options #{not_valid}", caller(1)
    end

    opt
end
wait_until(cycle) click to toggle source

Yields every cycle seconds until the block returns true.

# File lib/utilrb/kernel/poll.rb, line 11
def wait_until(cycle)
    until yield
        sleep(cycle)
    end
end
wait_while(cycle) click to toggle source

Yields every cycle seconds until the block returns false.

# File lib/utilrb/kernel/poll.rb, line 18
def wait_while(cycle)
    while yield
        sleep(cycle)
    end
end
with_module(*consts, &block) click to toggle source
# File lib/utilrb/kernel/with_module.rb, line 18
def with_module(*consts, &block)
    Thread.current[:__with_module__] ||= Array.new
    Thread.current[:__with_module__].push consts
    Kernel.send(:extend, WithModuleConstResolutionExtension)
    Object.extend WithModuleConstResolutionExtension

    eval_string =
        if !block_given? && consts.last.respond_to?(:to_str)
            consts.pop
        end
    if eval_string
        instance_eval(eval_string)
    else
        instance_eval(&block)
    end

ensure
    Thread.current[:__with_module__].pop
end