-
-
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
Macro lookup from included module broken #4639
Comments
Good catch, we need to investigate this soon. So the first suspect is this: c87fc6d |
Just wanted to state that Amber Framework is also breaking because of this behavior |
Unfortunately, this is not entirely resolved. For some reason the method lookup seems to be confused when an instance method of the same name is defined by a macro from an included module and the macro has already been called from the parent class. The following code results in module Include
macro foo
def foo
end
end
end
class Parent
include Include
foo
end
class Foo < Parent
foo
end Seems a bit strange, but it fails under exactly these conditions. Calling It works if |
@straight-shoota I'm not really into the details of this, but may it have to do something with This other program works: module Include
macro foo
def bar
puts "Hi there!"
end
end
end
class Parent
include Include
foo
end
class Foo < Parent
foo
end
Foo.new.bar |
Yes, this is a precondition for the improved macro lookup to fail. And it only happens if the macro has been invoked in a superclass (remove Btw. The failure is not depending on class hierarchy, it also errors if |
Sorry - I've forgot you explicitly stated the precondition on your message 👍 I think we don't care about this case that much. I don't see why you'd want to have a macro and a method with the same name. If you think this is really an issue, I think the best way would be to open a new issue and state some real use case for that, and we can consider it for a later version. For now, I think the issue is solved enough. |
I don't think this is kind of a feature request where you would describe a use case to advocate the issue, but it is clearly a bug where otherwise valid behavior breaks under very specific conditions. If macros and instance methods generally can share the same names without collision (which is the current state and makes absolute sense because they have very different scopes) this should work in any case and don't suddenly fail on arbitrary preconditions that might not even be too rare. A use case is a macro that acts as a generator for a synonymous method - it makes no sense to use different names. A real world example is this method (simplified from here): macro getattr(*whitelist)
def getattr(attr_name)
{% for method in whitelist %}
if {{ method.id.stringify }} == attr_name
return self.{{ method.id }}
end
{% end %}
end
end
# in a class that inherits this macro:
class UseCase
getter foo, bar
getattr foo, bar # => defines instance method `getattr` to access `#foo` and `#bar`
end If a another class inherits from |
@straight-shoota I understand that it may feel arbitrary, but there are probably more pressing needs now and with @asterite's fix this became just a corner case issue. We can leave this open to not lose track of the issue and revisit eventually, but we won't hold on To me that code looks a bit confusing, but in any case you could rename the macro to class UseCase
getter foo, bar
def_get_attr foo, bar # => defines instance method `get_attr` to access `#foo` and `#bar`
end Btw, took the liberty to rename |
Sure, I didn't want to push this for |
This was closed when @matiasgarciaisaia merged 0.23.1 branch into master (#4791) but this issue was not entirely resolved, so it should stay open. I could open a new issue if this would be preferred, but it feels like the same problem and was only partially fixed. |
True! Thanks for pointing out! :) |
In 0.23 the following code does no longer compile, in 0.22 it did. It might been caused by #236
I am not sure if this behaviour is intended, at least it should be mentioned in the release notes as breaking change.
This makes macro lookup behave like class method lookup in the same context of an included, but different from a parent class:
I would actually prefer to be able to call macros defined in modules from the including class scope and don't think they should be different from macros defined in a parent class. I think it is a common use case to define helper macros in a module and call these macros from class scope where this module is included. Now you need the extra verbosity of
Include.include_macro
and it is not possible to refer to the including type context, because with the explicit receiver,@type
points to the module, not the including class. So I would consider this a major breaking change - and probably a bug?The text was updated successfully, but these errors were encountered: