mojolicious / mojo

:sparkles: Mojolicious - Perl real-time web framework
https://mojolicious.org
Artistic License 2.0
2.66k stars 576 forks source link

v5.38 and module_true: File "/app/x.pl" did not return an application object #2094

Open melo opened 10 months ago

melo commented 10 months ago

Steps to reproduce the behavior

This is not a Mojolicious bug but a side effect of using v5.38 feature bundle. I'm creating the issue just to leave a note on this, for others that might see this error message.

Morbo fails to load app with error File "/app/x.pl" did not return an application object.

The minimal script:

use v5.38;
use Mojolicious::Lite -signatures; 
app->start;

Run with morbo:

$ morbo x.pl 
Web application available at http://127.0.0.1:3000
File "/app/x.pl" did not return an application object.

This works:

use v5.38;
no feature 'module_true';
use Mojolicious::Lite -signatures; 
app->start;

The feature bundle v5.38 activates the module_true feature. This adds an implicit return 1; at the end of the script file. To make it work we just need to unimport the feature.

Bye,

leonerd commented 10 months ago

Does it help if you wrote return app->start instead?

kraih commented 10 months ago

That sucks. We probably need an FAQ entry for this and recommend against the use of the v5.38 bundle with Mojolicious.

melo commented 10 months ago

Does it help if you wrote return app->start instead?

No, same error.

melo commented 10 months ago

That sucks. We probably need an FAQ entry for this and recommend against the use of the v5.38 bundle with Mojolicious.

I'll search for the FAQ and send a PR, glad to help.

leonerd commented 10 months ago

That sucks. We probably need an FAQ entry for this and recommend against the use of the v5.38 bundle with Mojolicious.

You can just

feature->unimport( 'module_true' ) if $^V ge v5.38;

in your main sub import

jberger commented 10 months ago

That sucks. We probably need an FAQ entry for this and recommend against the use of the v5.38 bundle with Mojolicious.

You can just

feature->unimport( 'module_true' ) if $^V ge v5.38;

in your main sub import

That's a little unfortunate too as then class files will still have to end in 1; though the users might not expect that (some of them at least). Is there any way we can detect that we're in a ::Lite context (and even as I ask it I'm almost certain the answer is no).

melo commented 10 months ago

Using @leonerd suggestion and adding the following

feature->unimport( 'module_true' ) if $^V ge v5.38;

before the goto Mojo::Base::import logic solves the issue.

Not sure if that is the way to go. I like it, and it is just scoped to the use of Mojolicious::Lite.

jberger commented 10 months ago

That will work until Mojo::Base's import would load 5.38, but that's a while off and even then we could probably inspect the hints hash to see if it has already been unimported from outside or something. I like it.

melo commented 10 months ago

@jberger I like it too, seems the most local and clean way to deal with it.

I experimented with (caller(1))[10] to see if I could find the feature_module_true in there, and if present, unimport it. Doesn't seem to work. When you use a feature bundle like use v5.38, the hints hash is undef.

edited: cute...

This sets the hint hash and I can see feature_module_true there:

use feature ':5.38';

but this doesn't set the hints hash:

use v5.38;

I still think just removing the feature is the way to go.

edited, again: I actually believe that the hint hash not been set when implicit bundle load is used to be a perl bug, so I also opened this: https://github.com/Perl/perl5/issues/21387

melo commented 10 months ago

Updated version of the fix, more precise:

feature->unimport( 'module_true' ) if feature::feature_enabled('module_true', 1);

edited: the feature::feature_enabled() function was released on 5.36, so cannot be used with Mojolicious, target is 5.16. Back to @jberger solution.