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
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 50 def attr_reader_lazy(name) 51 #$stderr.puts "attr_reader_lazy :#{name}" 52 varname = "@#{name}".intern 53 methodname = "__get__#{name}".intern 54 55 # module to reset method's behavior to normal attr_reader 56 reset = "Attr_#{name}".intern 57 const_set(reset, Module.new { attr_reader name }) 58 reset_module_name = "#{self}::#{reset}" 59 60 # define attr method 61 module_eval <<__END_OF_DEF__ 62 def #{name} 63 unless defined? #{varname} then 64 #$stderr.puts "LAZY #{name}: calling #{methodname}" 65 val = #{methodname}(@source_data) 66 #{varname} = val unless frozen? 67 else 68 val = #{varname} 69 end 70 unless frozen? then 71 #$stderr.puts "LAZY #{name}: finalize: attr_reader :#{name}" 72 self.extend(#{reset_module_name}) 73 end 74 val 75 end 76 __END_OF_DEF__ 77 end
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 93 def def_biosequence_adapter(name, source_method = name, &block) 94 methodname = "__get__#{name}".intern 95 96 if block then 97 define_method(methodname, block) 98 else 99 module_eval <<__END_OF_DEF__ 100 def #{methodname}(orig) 101 orig.#{source_method} 102 end 103 __END_OF_DEF__ 104 end 105 private methodname 106 attr_reader_lazy name 107 true 108 end