Issue #8088 has been updated by headius (Charles Nutter).


marcandre (Marc-Andre Lafortune) wrote:
> headius (Charles Nutter) wrote:
> > I was contemplating hacking something together myself, in fact. Would like to see what you're proposing...can you add an issue to CommonRuby?
> 
> I could, or maybe you and I can work on something together before submitting it?

I'm game to toss some ideas around. I don't know MRI internals well enough to implement much of it myself :-)

> My goals would be to be able to, at least:
> - know the minimum and maximum arity (where max can be unlimited). See #5747
> - know list of optional and mandatory keyword arguments, presence of keyrest. See #6086
> - know if a block can be passed. See #7299

Yup, good. In JRuby blocks can always be passed, but it would be nice to know if a block is required. Method#parameters will probably need some enhancement for that.

> I'm thinking of having something like:
> 
>   rb_define_method_x(rb_cString, "gsub", rb_str_gsub, "pattern, [replacement], [&]");
> 
> Although a string means some form of parsing, it also makes the API extensible as well as expressive. In any case, a string is required for named parameters.
> 
> Actually, we could even reuse rb_define_method, e.g.:
> 
>   rb_define_method_x(rb_cString, "gsub(pattern, [replacement], [&])", rb_str_gsub, 0);

Parsing is not unusual in MRI method logic anyway. When you have optional or keyword args, you have to pass in a formatted string that basically has this same info without names. So I don't think adding a format for specifying the argument list is unreasonable.

> > It would be super nice if it's possible to get actual C parameters, but I don't think you can do that programmatically (i.e. they'd have to be passed in).
> 
> Sorry, not sure what you mean.

In JRuby, because we're just marking up Java source for native methods, we can see (in addition to required count, optional count, rest arg present) the names of the arguments, whether the method will do anything with a block (but not whether it's required), and so on...all via Java's reflective capabilities. I don't think anything equivalent exists either at a C macro level or programmatically (e.g., I know there's nothing for inspecting a function pointer and getting argument information), so any information we want to present will have to be provided manually.

I have also considered expanding our annotations to mark up specific parameters as coerced (generating coercion code or type errors automatically) and to include richer information about variable arity call paths, keyword args, and so on. Potentially, we'd be able to mark up a normal Java method sorta like this:

public IRubyObject some_impl(IRubyObject @required arg0, IRubyObject @keyword foo, IRubyObject @keyword bar) ...

...and automatically pass keyword args into the "foo" and "bar" variables with no intermediate Hash. Lots of potential here.
----------------------------------------
Feature #8088: Method#parameters (and friends) should provide useful information about core methods
https://bugs.ruby-lang.org/issues/8088#change-37613

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


I was wiring up #parameters to work for native methods today when I realized MRI doesn't give very good information about variable-arity native methods:

ext-jruby-local ~/projects/jruby $ ruby2.0.0 -e "p ''.method(:gsub).to_proc.parameters"
[[:rest]]

ext-jruby-local ~/projects/jruby $ jruby -e "p ''.method(:gsub).to_proc.parameters"
[[:req], [:opt]]

I think MRI should present the same as JRuby here; gsub is obviously not a rest-arg method and you can't call it with less than 1 or more than 2 arguments. JRuby's presenting the right output here.

I'm probably going to have to change JRuby to do the less-helpful version so we're compliant and tests pass, but I think the specification of #parameters should be that it presents the JRuby version about rather than the MRI version.


-- 
http://bugs.ruby-lang.org/