-
Notifications
You must be signed in to change notification settings - Fork 227
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
[2.0.10 Regression] Methods defined in a template can't be used later in the template #347
Comments
Just experienced this issue as well after upgrading |
Yikes! Can you look into this @jeremyevans? |
https://github.com/hanami/hanami/issues/1015 seems to be a separate bug related to class scoping:
|
Taking a look now. I'm guessing the method issue is because we are not using the singleton class. Not sure about the hanami scope issue at this point. |
The issue with the method definition is because in 2.0.10, Note that a simple workaround for this issue is to use |
The hanami issue I'm not sure about, I would need the content of the template that is failing, the scope it is being executed on, and which constants are defined (or even better, a reproducible example). |
These issues show that the new behavior is not backwards compatible in all cases and probably cannot be made backwards compatible in such cases. However, the new behavior is necessary to continue to work on newer versions of Ruby, and offers significant performance benefits on all Ruby versions. Therefore, I propose we make it opt-in in older ruby versions, and required in ruby 2.7+. Alternatively, we release 2.0.11 with the changes reverted, and release 3.0.0 with the changes added back. |
By temporary removing this inheritance the broken tests passes again: diff --git a/lib/hanami/view/rendering/layout_scope.rb b/lib/hanami/view/rendering/layout_scope.rb
index 5c5fca3..a6ee651 100644
--- a/lib/hanami/view/rendering/layout_scope.rb
+++ b/lib/hanami/view/rendering/layout_scope.rb
@@ -16,7 +16,7 @@ module Hanami
# Scope for layout rendering
#
# @since 0.1.0
- class LayoutScope < BasicObject
+ class LayoutScope
# Initialize the scope
#
# @param layout [Hanami::Layout] the layout to render I cannot apply this patch above, because For instance, the HTML helper |
By debugging be625c8#diff-4757dfc1f8a5b4b4ab833adbe73c5785R169 I found an interesting, but confusing detail: When (byebug) scope
#<Hanami::View::Rendering::LayoutScope:7fbc05b25d90 @layout="#<LocalsLayout:0x00007fbc05ba5a40 @scope=#<Hanami::View::Rendering::LayoutScope:7fbc05b25d90 @layout="#<LocalsLayout:0x00007fbc05ba5a40 ...>" @scope="#<Hanami::View::Rendering::Scope: 7fbc05b25d90 @view="Hanami::View::Rendering::NullView" @locals="{:format=>:html}">">, @rendered="">" @scope="#<Hanami::View::Rendering::Scope: 7fbc05b25d90 @view="Hanami::View::Rendering::NullView" @locals="{:format=>:html}">">
(byebug) scope.is_a?(Module)
true When it implicitly inherits from (byebug) scope
#<Hanami::View::Rendering::LayoutScope:7fdc67add928 @layout="#<LocalsLayout:0x00007fdc67addc20 @scope=#<Hanami::View::Rendering::LayoutScope:7fdc67add928 @layout="#<LocalsLayout:0x00007fdc67addc20 ...>" @scope="#<Hanami::View::Rendering::Scope: 7fdc67add9f0 @view="Hanami::View::Rendering::NullView" @locals="{:format=>:html}">">, @rendered="">" @scope="#<Hanami::View::Rendering::Scope: 7fdc67add9f0 @view="Hanami::View::Rendering::NullView" @locals="{:format=>:html}">">
(byebug) scope.is_a?(Module)
false With the default scenario ( method = compiled_method(locals_keys, scope.is_a?(Module) ? scope : scope.class) I'm using this Ruby version: $ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin16] |
That makes sense. Alternatively, you could fix constant lookup for your class LayoutScope < BasicObject
def self.const_missing(name)
::Object.const_get(name)
end
end |
Actually, if you pass a diff --git a/lib/tilt/template.rb b/lib/tilt/template.rb
index 7f35cb2..9accf46 100644
--- a/lib/tilt/template.rb
+++ b/lib/tilt/template.rb
@@ -166,7 +166,12 @@ module Tilt
def evaluate(scope, locals, &block)
locals_keys = locals.keys
locals_keys.sort!{|x, y| x.to_s <=> y.to_s}
- method = compiled_method(locals_keys, scope.is_a?(Module) ? scope : scope.class)
+ case scope
+ when BasicObject
+ method = compiled_method(locals_keys, Kernel.instance_method(:class).bind(scope).call)
+ else
+ method = compiled_method(locals_keys, Module === scope ? scope : scope.class)
+ end
method.bind(scope).call(locals, &block)
end
However, then if you are using Erubi as the erb processor, it fails as well, because Erubi uses |
See rtomayko/tilt#347 for details.
FWIW, I'm personally fine with the suggested workaround of using |
I committed a fix to Erubi: jeremyevans/erubi@3db54fc @jodosha, can you try the Erubi master branch and see if that fixes the Hanami issue? |
@jeremyevans thanks for the quick patch on
|
I do believe that we actually intentionally said that constant lookup should be based in |
@jeremyevans You hit the point:
I cannot recall why By implementing The problem is solved for Hanami. Can I do something to help with |
@judofyr Unfortunately, you can't have constant lookup fallback to Object and have constant lookup based on the scope class and run without warnings on Ruby 2.7. If the scope class is subclassed from BasicObject, and you want to reference constants in Object without I'll push out a new release of Erubi today. |
Erubi 1.9.0 was released a few minutes ago. I'll work on a pull request to fix the rendering of BasicObject instances in tilt. |
I'm not sure if it's related, but since tilt 2.0.10 our cells have been breaking with:
|
I think we should close this. We aren't going to be reverting to the old design. If you want to define methods in a template and call them later in the template, use |
Agreed. Defining methods inside a template was never an intention of Tilt. You can always use lambdas ( |
Starting with Tilt 2.0.10, methods defined in a template can't be used later in the template, it seems. Here's a self-contained reproducer that works with Tilt 2.0.9, but not Tilt 2.0.10:
The output with Tilt 2.0.9 is
hello
, but the output with Tilt 2.0.10 is:The text was updated successfully, but these errors were encountered: