module Bio::Sequence::Adapter

Internal use only. Normal users should not use this module.

Helper methods for defining adapters used when converting data classes to Bio::Sequence class, with pseudo lazy evaluation and pseudo memoization.

This module is used by using “extend”, not “include”.

Private Instance Methods

attr_reader_lazy(name) click to toggle source

Defines a reader attribute method with psudo lazy evaluation/memoization.

It defines a method name like attr_reader, but at the first time when the method name is called, it acts as follows: When instance variable @name is not defined, calls __get__name(@source_data) and stores the returned value to @name, and changes its behavior to the same as attr_reader :name. When instance variable @name is already defined, its behavior is changed to the same as attr_reader :name. When the object is frozen, storing to the instance variable and changing methods behavior do not occur, and the value of __get__name(@source_data) is returned.

Note that it assumes that the source data object is stored in @source_data instance variable.

# File lib/bio/sequence/adapter.rb, line 50
  def attr_reader_lazy(name)
    #$stderr.puts "attr_reader_lazy :#{name}"
    varname = "@#{name}".intern
    methodname = "__get__#{name}".intern

    # module to reset method's behavior to normal attr_reader
    reset = "Attr_#{name}".intern
    const_set(reset, Module.new { attr_reader name })
    reset_module_name = "#{self}::#{reset}"

    # define attr method
    module_eval <<__END_OF_DEF__
      def #{name}
        unless defined? #{varname} then
          #$stderr.puts "LAZY #{name}: calling #{methodname}"
          val = #{methodname}(@source_data)
          #{varname} = val unless frozen?
        else
          val = #{varname}
        end
        unless frozen? then
          #$stderr.puts "LAZY #{name}: finalize: attr_reader :#{name}"
          self.extend(#{reset_module_name})
        end
        val
      end
__END_OF_DEF__
  end
def_biosequence_adapter(name, source_method = name, &block) click to toggle source

Defines a Bio::Sequence to Bio::* adapter method with psudo lazy evaluation and psudo memoization.

Without block, defines a private method __get__name(orig) which calls source_method for @source_data.

def__get__(name, source_method) is the same as:

def __get__name(orig); orig.source_method; end
attr_reader_lazy name

If block is given, __get__name(orig) is defined with the block. The @source_data is given as an argument of the block, i.e. the block must get an argument.

# File lib/bio/sequence/adapter.rb, line 93
  def def_biosequence_adapter(name, source_method = name, &block)
    methodname = "__get__#{name}".intern

    if block then
      define_method(methodname, block)
    else
      module_eval <<__END_OF_DEF__
        def #{methodname}(orig)
          orig.#{source_method}
        end
__END_OF_DEF__
    end
    private methodname
    attr_reader_lazy name
    true
  end