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

GSL_PREFIX =
"gsl_vector_"
GSL_MODULE =
::GSL4r::Vector

Instance Method Summary collapse

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