Hello again! I’ve found another piece of quirky behaviour inside Do
.
Consider this example: (fuller example with tests)
module ConvertToUpperCase
class SingletonDoAllShortcut
class << self
include Dry::Monads[:do, :try]
def call(string)
yield to_upper(string)
end
private
def to_upper(s)
Try { String(s).upcase }
end
end
end
end
ConvertToUpperCase::SingletonDoAllShortcut.call("pow!") # => LocalJumpError (no block given)
Do::All
does not behave as expected when invoked inside a singleton class. For whatever reason, the methods are not detected by Do::All
and so aren’t wrapped. When the code is invoked, the developer just sees LocalJumpError
exceptions. This was super-confusing when I first encountered it: it took me a while to believe the issue was with dry-rb
and not my development environment!
As demonstrated in the fuller example:
include Dry::Monads[:do] in the singleton class |
❌ |
include Dry::Monads::Do::All in the singleton class |
❌ |
include Dry::Monads::Do.for in the singleton class |
✅ |
include All in the main class, and call .new.call in the singleton class |
✅ |
Given the wider conventions outlined by dry-container
& dry-system
(Klass.new.call
is preferred over Klass.call
), I wouldn’t be surprised if this is a WONTFIX
issue - especially if a singleton-class wrapper is such a simple workaround!
I’d like to contribute to the documentation so this behaviour is less surprising (or at least easily-discoverable). How can I best do that?