Module: Svn::Utils::Extensions
- Defined in:
- lib/svn/utils.rb
Overview
this module contains extensions for classes that inherit from FFI::Struct and FFI::AutoPointer to make binding instance methods to C methods more concise
Class Method Summary collapse
-
.bind(sym, options = {}, &block) ⇒ Object
binds a method on the current target to self.
-
.bind_to(target) ⇒ Object
sets the module that will be used for all bound methods, until bind_to is called again.
Instance Method Summary collapse
-
#factory(*args) ⇒ Object
convenience method that returns a Factory instance for self with the given args.
Class Method Details
.bind(sym, options = {}, &block) ⇒ Object
binds a method on the current target to self
arguments
sym
-
the method on the target (set by
bind_to
) to use options
-
a Hash of optional method aliases or returned arguments
options
:as
-
method name to use for the bound method
:to
-
function name to use from the target object
:returning
-
an array of types for out parameters
:validate
-
a validation to call on the bound method’s return value
:before_return
-
a function to call on the return value
TODO: call to_proc on symbols that should be procs
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/svn/utils.rb', line 187 def bind( sym, ={}, &block ) # look up the method in the target module meth_name = ( [:to] || sym ).to_sym # get a method obj from the target receiver so that if @@target is # changed by another call to :bind_to, the method/target will not be # changed (and broken) meth = @@target.method( meth_name ) name = ( [:as] || sym ).to_sym # get the return types as an Array and save a copy single_return = ![:returning].is_a?( Array ) return_types = Array( [:returning] ).dup # get the C function validation validation = [:validate] # get the before_return filter before_return = [:before_return] || lambda { |x| x } # create a new method; blocks are used to re-arrange arguments define_method( name ) do |*args| # create new pointers for the specified out arguments return_ptrs = return_types.map { |type| FFI::MemoryPointer.new( type ) } # create the argument list for the function call_args = return_ptrs.dup call_args << self call_args += args return_val = nil # keep it in scope if block # call the method with the arguments after re-arranging via block return_val = meth.call( *instance_exec( *call_args, &block ) ) else # call the method with the standard argument order return_val = meth.call( *call_args ) end # call the return check, if present instance_exec( return_val, &validation ) if validation # if there are return types (out pointers), read the values out of # the pointers and replace the return_val unless return_types.empty? return_val = return_ptrs.zip( return_types ).map do |ptr, type| Utils.content_from( ptr, type ) end return_val = return_val.first if single_return end # run the before_return filter and return the value from it; if no # :before_return was in options, this will be the id function instance_exec( return_val, &before_return ) end end |
.bind_to(target) ⇒ Object
sets the module that will be used for all bound methods, until bind_to is called again
169 170 171 |
# File 'lib/svn/utils.rb', line 169 def bind_to( target ) @@target = target end |
Instance Method Details
#factory(*args) ⇒ Object
convenience method that returns a Factory instance for self with the given args
the following are equivalent:
NativeHash.factory( :string, :string )
Factory( NativeHash, :string, :string )
161 162 163 |
# File 'lib/svn/utils.rb', line 161 def factory( *args ) Factory.new( self, *args ) end |