What I want to do is basically:
# @param [class] cls
# @return [instanceof(cls)]
def get(cls)
# Imagine this is method and object has property @instances = {}
if [email protected]?(cls)
@instances[cls] = cls.new()
end
@instances[cls]
end
It can be very handy for the service container pattern, when using it like
service = container.get(MyClass) # language server (e.g. solargraph) will see service variable as of type MyClass
Is it possible with YARD?
UPDATE:
fixed example of function, it did return simply cls.new() in the past
Just Declare a Type or Duck-Type in Your Return Tag
YARD already does this. What you're likely misunderstanding is how YARD uses brackets to document the type of the return value. You're also welcome to add free-form descriptions if you really feel it's necessary. However, pragmatically speaking, you're really just expecting your cls argument to respond to #new, so I'd rewrite it (and make it slightly more idiomatic) like so:
If you want to be more explicit, you could change the type in the @param tag to:
so that it's clear that you're expecting a Class, but will also accept a duck-typed object that responds to #new. Since the method is exactly one line long, I think it's pretty unambiguous either way, especially with the description. Your taste and code style may vary, though.
In either case, the square brackets should declare one or more types, even if they're duck-types. So, yes, you can do what you want.
Ruby 3.2 Note
Unless something changes in the next month, in Ruby 3.2.0 you can make this even shorter with an "endless" method definition. For example, using ruby-3.2.0-preview2:
Whether or not you like the new syntax, it certainly works. For example:
This isn't better or worse than the old syntax, but I do think it lets you tighten up the code and the documentation while increasing clarity. Again, your mileage may vary.