Module: GSL4r::Util::AutoPrefix
- Included in:
- Block::GSL_Block, Complex::GSL_Complex, Vector::GSL_Vector
- Defined in:
- lib/gsl4r/util.rb,
lib/gsl4r/vector.rb
Overview
attach_gsl_function
Constant Summary collapse
Instance Method Summary collapse
-
#method_missing(called_method, *args, &block) ⇒ Object
This traps method calls intended to create shortened versions of the GSL function calls.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(called_method, *args, &block) ⇒ Object
This traps method calls intended to create shortened versions of the GSL function calls.
This first checks if the called method matches the Module function call gsl_complex_#called_method (where called_method might be ‘abs’).
If it finds a match (respond_to), it will then create a new method for the class as a whole (class_eval), making the method available to not just this instance of the class, but all existing instances and all those created after.
Finally, the creation is wrapped up in a synchronized call to ensure thread safety. It is only unsafe the first time the method is invoked (and non-existent at that point). Every time the method is invoked after, it should not hit method_missing. TODO: Is this true for java threads too, or is it per ‘vm’ per thread?
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/gsl4r/util.rb', line 116 def method_missing( called_method, *args, &block ) $prefixLock.synchronize do prefix = self.class::GSL_PREFIX if ( self.class::GSL_MODULE::Methods.respond_to?("#{prefix}#{called_method}") == false ) prefix = "" if ( self.class::GSL_MODULE::Methods.respond_to?("#{called_method}") == false ) super # NoMethodError end end # TODO: this could be smoothed out with the #args/#parameters parts of # Ruby 1.9. # This could inspect the definition of the parameter and if the # first argument in the definition were of the same type as self # then self could be inserted into the args list per below # rather than requiring the #{called_method.to_s.upcase}_ADD_SELF # boolean definition and check self.class.class_eval <<-end_eval def #{called_method}(*args, &block) if ::#{self.class::GSL_MODULE.to_s}::Methods::#{prefix.to_s.upcase}#{called_method.to_s.upcase}_ADD_SELF args.insert(0, self) end ::#{self.class::GSL_MODULE.to_s}::Methods::#{prefix}#{called_method}( *args, &block ) end end_eval __send__(called_method, *args, &block) end # prefixLock.synchronize end |