Method: RubyPython::RubyPyProxy#method_missing
- Defined in:
- lib/rubypython/rubypyproxy.rb
#method_missing(name, *args, &block) ⇒ Object
Delegates method calls to proxied Python objects.
Delegation Rules
-
If the method ends with a question-mark (e.g.,
nil?), it can only be a Ruby method on RubyPyProxy. Attempt to reveal it (RubyPyProxy is a BlankObject) and call it. -
If the method ends with equals signs (e.g.,
value=) it’s a setter and we can always set an attribute on a Python object. -
If the method ends with an exclamation point (e.g.,
foo!) we are attempting to call a method with keyword arguments. -
The Python method or value will be called, if it’s callable.
-
RubyPython will wrap the return value in a RubyPyProxy object (unless legacy_mode has been turned on).
-
If a block has been provided, the wrapped return value will be passed into the block.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 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 |
# File 'lib/rubypython/rubypyproxy.rb', line 142 def method_missing(name, *args, &block) name = name.to_s if name =~ /\?$/ begin RubyPyProxy.reveal(name.to_sym) return self.__send__(name.to_sym, *args, &block) rescue RuntimeError => exc raise NoMethodError.new(name) if exc. =~ /Don't know how to reveal/ raise end end kwargs = false if name =~ /=$/ return @pObject.setAttr(name.chomp('='), PyObject.convert(*args).first) elsif name =~ /!$/ kwargs = true name.chomp! "!" end raise NoMethodError.new(name) if !@pObject.hasAttr(name) pFunc = @pObject.getAttr(name) if pFunc.callable? if args.empty? and pFunc.class? pReturn = pFunc else if kwargs and args.last.is_a?(Hash) pKeywords = PyObject.convert(args.pop).first end orig_args = args args = PyObject.convert(*args) pTuple = PyObject.buildArgTuple(*args) pReturn = if pKeywords pFunc.callObjectKeywords(pTuple, pKeywords) else pFunc.callObject(pTuple) end # Clean up unused Python vars instead of waiting on Ruby's GC to # do it. pFunc.xDecref pTuple.xDecref pKeywords.xDecref if pKeywords orig_args.each_with_index do |arg, i| # Only decref objects that were created in PyObject.convert. if !arg.kind_of?(RubyPython::PyObject) and !arg.kind_of?(RubyPython::RubyPyProxy) args[i].xDecref end end raise PythonError.handle_error if PythonError.error? end else pReturn = pFunc end result = _wrap(pReturn) if block block.call(result) else result end end |