class Module

Public Instance Methods

__include_single_module(mod) click to toggle source
# File lib/utilrb/module/include.rb, line 22
def __include_single_module(mod)
    if mod.const_defined?(:ModuleExtension)
        if is_a?(Module)
            unless const_defined?(:ModuleExtension)
                const_set(:ModuleExtension, Module.new)
            end
            const_get(:ModuleExtension).class_eval do
                __instance_include__ mod.const_get(:ModuleExtension)
            end
            extend mod.const_get(:ModuleExtension)
        end
        # Do nothing on classes
    end
    if mod.const_defined?(:ClassExtension)
        if !is_a?(Class)
            unless const_defined?(:ClassExtension)
                const_set(:ClassExtension, Module.new)
            end
            const_get(:ClassExtension).class_eval do
                __instance_include__ mod.const_get(:ClassExtension)
            end
        else
            extend mod.const_get(:ClassExtension)
        end
    end

    __instance_include__ mod
end
__instance_include__(*mods)
Alias for: include
attr_enumerable(name, attr_name = name, enumerator = :each, &init_block) click to toggle source

Support for attributes that are enumerables. This methods defines two methods:

obj.attr_name # => enumerable
obj.each_name(key = nil) { |value| ... } # => obj

The first one returns the enumerable object itself. The second one iterates on the values in attr_name. If key is not nil, then attr_name is supposed to be a hash of enumerables, and key is used to select the enumerable to iterate on.

The following calls are equivalent

obj.attr_name.each { |value| ... }
obj.each_name { |value| ... }

And these two are equivalent:

obj.attr_name[key].each { |value| ... }
obj.each_name(key) { |value| ... }

enumerator is the name of the enumeration method we should use. init_block, if given, should return the value at which we should initialize attr_name.

# File lib/utilrb/module/attr_enumerable.rb, line 25
    def attr_enumerable(name, attr_name = name, enumerator = :each, &init_block)
        class_eval do
            attribute(attr_name, &init_block)
        end
        class_eval <<-EOF, __FILE__, __LINE__+1
            def each_#{name}(key = nil, &iterator)
                return unless #{attr_name}
                if key
                    #{attr_name}[key].#{enumerator}(&iterator)
                else
                    #{attr_name}.#{enumerator}(&iterator)
                end
                self
            end
        EOF
    end
attr_predicate(name, writable = false) click to toggle source

Defines a name? predicate, and if writable is true a name= method. Note that name can end with '?', in which case the ending '?' is removed.

The methods use the @name instance variable internally

# File lib/utilrb/module/attr_predicate.rb, line 7
def attr_predicate(name, writable = false)
    attr_name = name.to_s.gsub(/\?$/, '')
    attr_reader attr_name
    alias_method "#{attr_name}?", attr_name
    remove_method attr_name

    if writable
        class_eval "def #{attr_name}=(value); @#{attr_name} = !!value end", __FILE__, __LINE__+1
    end
end
cached_enum(enum_name, name, with_arg) click to toggle source

Creates enum_#{name} method which returs an Enumerator object for the each_#{enum_name} method. This enumerator is created once.

If with_arg is true, it is supposed that the 'each_' method requires one argument, which is given in argument of the 'enum' method. In that case, an enumerator is created for each argument

# File lib/utilrb/module/cached_enum.rb, line 21
    def cached_enum(enum_name, name, with_arg)
        include CachedValuesSupport
        if with_arg
            class_eval <<-EOD, __FILE__, __LINE__+1
                def enum_#{name}(arg)
                    @enum_#{name} ||= Hash.new
                    cached_variables << :@enum_#{name}
                    @enum_#{name}[arg] ||= enum_for(:each_#{enum_name}, arg)
                end
                EOD
        else
            class_eval <<-EOD, __FILE__, __LINE__+1
                def enum_#{name}
                    cached_variables << :@enum_#{name}
                    @enum_#{name} ||= enum_for(:each_#{enum_name})
                end
                EOD
        end
    end
const_defined_here?(name) click to toggle source
# File lib/utilrb/module/const_defined_here_p.rb, line 3
def const_defined_here?(name)
    const_defined?(name, false)
end
define_method_with_block(name, &mdef) click to toggle source

Emulate block-passing by converting the block into a Proc object and passing it to the given block as last argument dule)

For instance

define_method('my_method') do |a, &block|
end

Is written as

define_method_with_block('my_method') do |block, a|
end

The block is given first to allow the following construct:

define_method_with_block('my_method') do |block, *args|
end

block is nil if no block is given during the method call

# File lib/utilrb/module/define_method.rb, line 21
    def define_method_with_block(name, &mdef)
        class_eval <<-EOD, __FILE__, __LINE__+1
            def #{name}(*args, &block)
                dmwb_#{name}_user_definition(block, *args) 
            end
        EOD
        define_method("dmwb_#{name}_user_definition", &mdef)
    end
define_or_reuse(name, value = nil) { || ... } click to toggle source

:call-seq

define_or_reuse(name, value)   ->              value
define_or_reuse(name) { ... }  ->              value

Defines a new constant under a given module, or reuse the already-existing value if the constant is already defined.

In the first form, the method gets its value from its argument. In the second case, it calls the provided block

# File lib/utilrb/module/define_or_reuse.rb, line 12
def define_or_reuse(name, value = nil)
    if const_defined_here?(name)
        const_get(name)
    else
        module_eval do
            const_set(name, (value || yield))
        end
    end
end
dsl_attribute(name) click to toggle source
dsl_attribute(name,name2,name3)
dsl_attribute(name) { |value| ... }

This defines a name instance method on the given class which accepts zero or one argument

Without any argument, it acts as a getter for the +@name+ attribute. With one argument, it acts instead as a setter for the same attribute and returns self. If a block has been given to dsl_attribute, any new value is passed to the block, whose return value is actually saved in the instance variable. This block can therefore both filter the value (convert it to a desired form) and validate it.

The goal of this method is to have a nicer way to handle attribute in DSLs: instead of

model = create_model do
   self.my_model_attribute = 'bla'

   if (my_model_attribute)
       <do something>
   end
end

(or worse, using set_ and get_ prefixes), we can do

model = create_model do
   my_model_attribute 'bla', arg0, arg1, ...

   if (my_model_attribute)
       <do something>
   end
end
# File lib/utilrb/module/dsl_attribute.rb, line 37
def dsl_attribute(*names, &filter_block)
    if names.size > 1 && filter_block
        raise ArgumentError, "multiple names as argument are only supported if no block is given"
    end
    names.each do |name|
    class_eval do
        if filter_block
            define_method("__dsl_attribute__#{name}__filter__", &filter_block)
        end

        define_method(name) do |*value|
            if value.empty?
                instance_variable_get("@#{name}")
            elsif filter_block
                if filter_block.arity >= 0 && value.size != filter_block.arity
                    raise ArgumentError, "too many arguments. Got #{value.size}, expected #{filter_block.arity}"
                end

                filtered_value = send("__dsl_attribute__#{name}__filter__", *value)
                instance_variable_set("@#{name}", filtered_value)
                self
            else
                if value.size == 1
                    instance_variable_set("@#{name}", value.first)
                else
                    instance_variable_set("@#{name}", value)
                end
                self
            end
        end
    end
    end
end
include(*mods) click to toggle source

Includes a module in this one, with support for class extensions

If a module defines a ClassExtension submodule, then

  • if it is included in a module, the target's ClassExtension module includes the source ClassExtension (and if there is no ClassExtension in the target, it is created)

  • if it is included in a Class, the ClassExtension module extends the class.

# File lib/utilrb/module/include.rb, line 16
def include(*mods)
    mods.each do |mod|
        __include_single_module(mod)
    end
end
Also aliased as: __instance_include__
is_singleton?()
Alias for: singleton_class?
singleton_class?() click to toggle source

It so happens that this method to determine whether a class is a singleton class is valid for ruby 2.0 and breaks on 2.1 … However (!) on 2.1 singleton_class? is defined

# File lib/utilrb/module/singleton_class_p.rb, line 6
def singleton_class?
    if instance_variable_defined?(:@__utilrb_singleton_class)
        @__utilrb_singleton_class
    else
        @__utilrb_singleton_class = (ancestors.first != self)
    end
end
Also aliased as: is_singleton?