module RubyPy
Ruby wrapper for Python modules (based on the PyCall gem).
Public Class Methods
import(pym)
click to toggle source
Import a python.module
as a RubyPy::Python::Module
using the PyCall gem. Methods called on the Ruby module will be sent to the Python module.
# File lib/ruby.py.rb, line 11 def self.import(pym) # very simple filter to mitigate the risk of code injection attacks raise ArgumentError unless pym =~ /\A[-_.A-Za-z0-9]+\Z/ # convert a python.module.name to a [RubyPy::]Python::Module::Name mod = pym.split('.').map do |segment| segment.split('_').map(&:capitalize).join end # create the [RubyPy::]Python::Module::Name hierarchy create_module_hierarchy = \ mod.size.times.map { |i| "module #{mod[0..i].join('::')};end" }.join(';') instance_eval(create_module_hierarchy, __FILE__, __LINE__) # import the python module into an anonymous module and delegate to it instance_eval("#{<<-"DEFMOD"}\n#{<<-"ENDMOD"}", __FILE__, __LINE__) DEFMOD module #{mod.join('::')} unless @_pycall def self._pycall @_pycall ||= Module.new do extend ::PyCall::Import pyimport #{pym.inspect}, as: 'import' end end def self.method_missing(method_name, *arguments, &block) if respond_to_missing?(method_name) _pycall.import.send(method_name, *arguments, &block) else super end end def self.respond_to_missing?(method_name, include_private = false) _pycall.import.respond_to?(method_name, include_private) end end self end ENDMOD end