From: merch-redmine@... Date: 2019-07-05T22:59:51+00:00 Subject: [ruby-core:93568] [Ruby master Bug#11214] Cannot Get Correct Binding from inside of C Method Issue #11214 has been updated by jeremyevans0 (Jeremy Evans). Status changed from Open to Feedback I'm fairly sure having `binding` capture arguments passed to C methods is not possible. Ruby doesn't know the C function's parameter names at runtime. Even if that were possible, you wouldn't be able to handle cases where a C function takes a variable number of arguments (`VALUE func(int argc, VALUE *argv, VALUE self)`). So that's why the binding does not include C-level information. It is similar to not being able to get the parameter names for methods defined in C via `Method#parameters`. In terms of why `binding` returns variables from the surrounding scope if called from C, I'm not sure. I think the only alternative would be raising an exception. I'm guessing we don't want to change the behavior, as there are libraries that appear to be relying on it: * https://github.com/FluxAugur/danddnext/blob/e0c4371527569970243ca1a76768ae0ced015474/vendor/gems/interception-0.5/ext/interception.c#L31 * https://github.com/Charo-IT/libgdbruby/blob/3109f4b3da26dbe7d7e723936ce332d7c57353be/libgdbruby/libgdbruby.cpp#L170 * https://github.com/tario/evalmimic/blob/3bf84e38ceb03ffc4fe5cfd41da63bb501e0f118/ext/evalmimic_base/evalmimic_base.c#L35 Do you still consider this a bug? ---------------------------------------- Bug #11214: Cannot Get Correct Binding from inside of C Method https://bugs.ruby-lang.org/issues/11214#change-79142 * Author: schneems (Richard Schneeman) * Status: Feedback * Priority: Normal * Assignee: * Target version: * ruby -v: 2.2.2 * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- I am trying to get the arguments passed into a method using the binding. This is possible using pure Ruby: ```ruby class RubyBindingClass def foo(arg = nil) return binding end end binding = RubyBindingClass.new.foo puts binding.eval("self") # => # puts binding.local_variables.inspect # => [arg] ``` You can see that the `#` is returned as self and the `local_variables` correctly reports that `arg` is in scope. When we access the binding from a C method, we do not get the same information ```ruby # Thanks to Frederick Cheung for the code snippet require 'inline' # $ gem install RubyInline random_main_variable = 2 class CBindingClass inline do |builder| builder.include "" builder.c_raw <<-SRC, :arity => 1 VALUE foo(VALUE self, VALUE arg){ VALUE ret = rb_funcall(self, rb_intern("binding"), 0); return ret; } SRC end end binding = CBindingClass.new.foo(10) puts binding.eval("self") # => main puts binding.local_variables.inspect # => [:binding, :random_main_variable] ``` Here you can see that self is reported as `main` and that `local_variables` is returning variables from the main scope instead of from within the C method. I originally stumbled upon this while trying to get access to arguments via TracePoint: http://stackoverflow.com/questions/30584454/get-method-arguments-using-rubys-tracepoint. Is this binding behavior intentional? Should it be possible to get programatic access to arguments passed into a C defined method? -- https://bugs.ruby-lang.org/ Unsubscribe: