-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
super
and previous_def
ignore block arguments
#10399
Comments
painfully working my way around crystal-lang/crystal#10399
I don't think this is a bug? In the end there's one overload with a block and one without one. In reality I think we might need to change the language so that if a method exists in a type then methods are looked up in just the type. If ko overload matches it's an error. Parent methods are only looked up if no method with that name exist in the child. I'll later send examples with code. But with the current semantics this isn't a bug. |
I do consider this an error, as the actual behavior isn't consistent. What I would expect is to |
Since the first call to |
How do you know that? What if |
I know that because the |
Isn't that exactly what's happening right now? class Foo
def foo
yield
end
end
class Bar < Foo
def foo
super # Error: undefined method 'foo' for Object
end
end
Bar.new.foo |
I don't think I have a preference about the behavior but it would certainly help to improve the error message, though perhaps that's tracked somewhere else. Run this code on Crystal 1.6.2: require "colorize"
class Foo
def only_if_coordinator : Nil
yield
end
end
class Bar < Foo
def only_if_coordinator : Nil
if false
yield
else
super
end
end
end
b = Bar.new
b.only_if_coordinator do
pp "blah"
end
Which doesn't provide any helpful guidance on why it can't find a method, or why it's looking at Colorize::ObjectExtensions. The source of that name is certainly some bubbling up behavior where it's looking for the appropriate |
The previous_def and super keywords do not propagate blocks. See: crystal-lang/crystal#10399 This works around the issue by populating arguments if the method uses a block.
painfully working my way around crystal-lang/crystal#10399
* implements a distributed lock for worker coordination The distributed lock system is stable up until the point that the redis cluster needs multiple masters. * refactors runner into logical separations splits into coordinator/executor/queue_list * simplifies naming and log messages re: delayed/periodic management * flags run_cron_scheduler as deprecated the usage has been removed completely * provides overseer, run_at_most for runner refactor * Move spin loop into overseer Runner is now simply the api to affect the overseer, and it will be the place for multiple overseer threads to attach * tests for coordinator * tests for queuelist * tests for overseers * tests for executor * tests for run_at_most * tests for log messages from executor * final testing cleanup for runner refactor * refactor run_at_most for monotonic * refactors Base.job_for_type to use String.build * tests for coordinator locking painfully working my way around crystal-lang/crystal#10399 * tests for backend lock methods * tests for coordinator locking * give a little grace to scheduled job test time constraint * allows script failures due to database flush to be caught and rescued * refactors lock_test to ensure locks are always unlocked prevents intermittent test failures * refactor: switch let statements to getter statements * changelog entries * disables distributed lock functionality by default, opt-in for now
The following:
only prints 1, whereas the same code prints also 2 and 3 in Ruby. Passing the wrong arguments to
Bar#foo
shows that these two overloads are defined:Bar#foo()
Foo#foo(&block)
On the other hand,
Bar.new.foo
produces anundefined method 'foo' for Object
error on thesuper
call without a block. Similar errors also happen forprevious_def
. The current workaround is to declare a block and forward it manually, but now any other method parameters must also be manually forwarded insuper
:Ideally we should detect that
Bar#foo
in fact accepts a block, but is this possible? Or shouldsuper
require a block argument if and only if the enclosing def uses a block elsewhere? (Note that both cases imply the block must be captured.)The text was updated successfully, but these errors were encountered: