Support for describing the arguments and return values of Proc/lambda arguments

288 views
Skip to first unread message

cmdr.s...@gmail.com

unread,
Oct 3, 2018, 4:39:43 PM10/3/18
to YARD
Hey folks.  I consulted https://yardoc.org/types.html and also Googled for an answer to this, in addition to searching the issues on https://github.com/lsegal/yard and searching this group.  I've come up short so far.  If I've missed an earlier discussion, please point me to it.  Posting here because https://github.com/lsegal/yard/blob/master/CONTRIBUTING.md says this is where feature requests belong.

I'd like to know a YARD type-syntax for describing "an argument that is a Proc/lambda which accepts <argument list>, and returns <return value> or raises <exception>".  Note, this is distinct from @yield / @yieldparam / @yieldreturn since it's not a block, and a method may accept multiple such parameters.  Example:

my_method name: "fred", event_handler: ->(symbol, count) { ... return a value ...}, error_handler: ->(symbol) { ... raise an exception ... }

Thanks,
Greg

Loren Segal

unread,
Oct 3, 2018, 6:20:50 PM10/3/18
to yar...@googlegroups.com
Just to clarify here, are you looking to accept any callable proc/lambda that accepts any set of arguments/return type, or are the arguments/return type fixed and specific to the "event_handler" / "error_handler" arguments?

Loren
--

---
You received this message because you are subscribed to the Google Groups "YARD" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yardoc+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gregory Meyers

unread,
Oct 4, 2018, 5:36:17 AM10/4/18
to yar...@googlegroups.com
Yes, the latter.  Ideally, I'd be able to annotate the lambda's signature (arguments, return value, exceptions) in all the same ways I can already annotate a method's signature.  Using the example, I'd like to make clear that the event_handler argument is a Proc that takes two arguments, the first being a Symbol and the second a Number, and that it's expected to return a value of type EventResponse or nil, and so on.  (This particular API is made up, naturally, it's just to illustrate the ask.)  If some arguments are mandatory and others optional, that would be nice to include too.

Of course I can simply describe it as a Proc, and then go into more detail in the main body of the method description; that's what I'm doing now.  I'd just prefer it to be as expressive as, for example, Hashes which let you give the key and value types.

I'm reluctant to invent a syntax (I should leave that to YARD's developers)... but if it were me, I'd work Ruby's new lambda ->() operator into it somehow.

Greg

You received this message because you are subscribed to a topic in the Google Groups "YARD" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/yardoc/gxxe2MNtp5A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to yardoc+un...@googlegroups.com.

Loren Segal

unread,
Oct 4, 2018, 4:52:39 PM10/4/18
to yar...@googlegroups.com, cmdr.s...@gmail.com

There are a couple of things here:

The YARD type specification is free-form, because anything we define is fundamentally at odds with Ruby syntax in many ways. YARD core doesn't _really_ define syntaxes except to make suggestions about what looks good. All of this is a middle ground between formal specification and prose. When you hit the edges of that specification (as this case does), you usually want to use the specification as a base to guide a discussion in prose. Ultimately, you will need to use both the specifier and prose to explain things.

A good example of this is the "raise EXC" part of your spec. Even if there was a "formal specification" of what raise EXC means in YARD tags, it still doesn't really explain how the potential raised exception will be handled in the context of your callback. Will you throw that exception out of the method? Is the method going to handle it? Is there a special exception that might be handled and others not (like a StopIteration)? This fundamentally can't be specified and needs prose to aid in the understanding process.

For that reason, I would keep it simple and use as little specification as possible to (a) make it clear what is expected but (b) without confusing the user. I assume your interface is actually going through #call(*args), therefore you can consider something like:

#call<(Symbol, Numeric)> returns String raises EXC

YARD types parser chokes on the "returns", but basically turns into:

a #call of (an Array containing (a Symbol followed by a Numeric)) returns String raises EXC

You can use : instead of returns if you don't want to be so verbose which would be:

a #call of (an Array containing (a Symbol followed by a Numeric)): String raises EXC

That to me is understandable enough and gives you a jumping off point in your @param prose to explain what you mean by all of that spec.

Hope that helps!

Loren
Reply all
Reply to author
Forward
0 new messages