Confused about types and globals
I'm trying to get my head around Dancer2, and am having trouble because it doesn't look entirely like Perl to me. For example: get '/foo/*' => sub { .... What is "get", exactly? I assume it is a function that takes a string and a coderef, and you're taking advantage of Perl's optional parentheses and fat comma to create a Perl-based DSL. The problem is, I can only find examples and tutorial docs, not a reference that outright confirms that, so I'm left with this uneasy feeling that I don't truly understand what's going on here yet. I tried to answer this myself before posting. I thought it might be a package-global function, but there is no "sub get" in Dancer2.pm. I also tried looking for a POD reference page on metacpan that explains this, but it ends up being a fully manual search since the metacpan search engine can't help with a generic term like 'get', and there are ~50 namespace pages to dig through. Another example: context->destroy_session The only way I can think of for that to work without a sigil is for 'context' to be another global (?) function that returns an object reference, rather than be an object reference itself. There is no "context" in Dancer2.pm, so I'm left wondering where it comes from. In one place, the tutorial docs say it is passed in to a "before" handler, while in other places it is assumed that you can just *use* this entity without having one passed into the route handler. I care about this because I'm trying to port a fairly complex app from Apache::ASP to Dancer2, and this app is already broken up into many separate modules. Because of this, the tutorial docs' assumption that I am writing all of my server-side code within the top-level module's route handlers doesn't apply. I'm not going to consolidate dozens of modules of code into this one module, just to solve the namespace problems. That just trades one problem for another. Ideally, I want my top-level module to be as small as possible, doing little more than set up the route handlers, delegating all the real work to other modules. To do that, I need to know where these objects come from, their exact data type, and which package's namespace they live in. Then I'll know how to reference them or pass them around to the modules that do the work in my app.
On Thu, Jan 23, 2014 at 9:18 AM, Warren Young <warren@etr-usa.com> wrote:
get '/foo/*' => sub { ....
What is "get", exactly? I assume it is a function that takes a string and a coderef, and you're taking advantage of Perl's optional parentheses and fat comma to create a Perl-based DSL.
Exactly. A lot of Dancer is Perl-based DSL. It "prettier" than this: get( '/foo/*', sub { ... } )
I tried to answer this myself before posting. I thought it might be a package-global function, but there is no "sub get" in Dancer2.pm.
Dancer2 (unlike Dancer1) has a rather convoluted system for exporting functions to the right place. It's sort of defined in Dancer2::Core::DSL, but those functions get wrapped in something that provide the right "application" object when used. E.g. https://metacpan.org/source/XSAWYERX/Dancer2-0.11/lib/Dancer2/Core/DSL.pm#L1...
Another example: context->destroy_session
The only way I can think of for that to work without a sigil is for 'context' to be another global (?) function that returns an object reference, rather than be an object reference itself.
Exactly.
There is no "context" in Dancer2.pm, so I'm left wondering where it comes from.
It's another DSL keyword: https://metacpan.org/source/XSAWYERX/Dancer2-0.11/lib/Dancer2/Core/DSL.pm#L2...
I care about this because I'm trying to port a fairly complex app from Apache::ASP to Dancer2, and this app is already broken up into many separate modules.
As I've mentioned before on this list, I consider Dancer2 to be alpha quality as it is still in active development and is thus not stable (though it is getting better). I would absolutely not port anything important or complex to Dancer2. David -- David Golden <xdg@xdg.me> Take back your inbox! → http://www.bunchmail.com/ Twitter/IRC: @xdg
On 1/23/2014 07:58, David Golden wrote:
On Thu, Jan 23, 2014 at 9:18 AM, Warren Young <warren@etr-usa.com> wrote: A lot of Dancer is Perl-based DSL. It "prettier" than this:
get( '/foo/*', sub { ... } )
Okay, thanks.
Dancer2 (unlike Dancer1) has a rather convoluted system for exporting functions to the right place.
Okay, I think I get it. I need to use this context "keyword" in my lib/App.pm file to get a Dancer2::Core::Context object that I can pass into my other modules, since the context keyword only exists in the App.pm module, the templates, and other files that Dancer2 has explicit knowledge of. Because it isn't really a global function, there's no other way I can get this object reference into a module Dancer2 doesn't know about.
I care about this because I'm trying to port a fairly complex app from Apache::ASP to Dancer2, and this app is already broken up into many separate modules.
As I've mentioned before on this list, I consider Dancer2 to be alpha quality as it is still in active development and is thus not stable (though it is getting better). I would absolutely not port anything important or complex to Dancer2.
We've probably got 6-12 months before we'll have to have a shipping version of our transplanted app. Is there any hope that Dancer2 will stabilize during that time? We don't want to go through all this work, then be looking at another big rewrite 2-3 years from now because Dancer1 has become a ghost town, as Apache::ASP is now. Apache::ASP served us for 12 years. We'd like to get another 12 out of our next framework.
On 1/23/2014, 10:54 AM, Warren Young wrote:
Is there any hope that Dancer2 will stabilize during that time?
It's hard to say. Most of the Dancer team is working on the project during the little free time they have, so progress tends to come in sporadic spurts.
We don't want to go through all this work, then be looking at another
big rewrite 2-3 years from now because Dancer1 has become a ghost town, as Apache::ASP is now. It's always possible that Dancer itself as a platform will fall out of favor. But as for the eventual eclipsing of Dancer1 for Dancer2, I think it's less of a adoption danger. The DSL and most of the interface are the same for both incarnation. Migrating a project from Dancer 1 to Dancer 2 should be a matter of a few tweaks and nothing close to a rewrite (and I know, I keep going back and forth between D1 and D2 in my own stuff). Of course, there are also the state of the plugins to consider on both incarnation, but usually if there a plugin missing for one version, it doesn't take long for somebody to migrate it. Joy, `/anick
On Thu, Jan 23, 2014 at 2:18 PM, Warren Young <warren@etr-usa.com> wrote:
Ideally, I want my top-level module to be as small as possible, doing little more than set up the route handlers, delegating all the real work to other modules. To do that, I need to know where these objects come from, their exact data type, and which package's namespace they live in. Then I'll know how to reference them or pass them around to the modules that do the work in my app.
When you say "the modules that do the work in my app" I'm assuming you mean the model in an MVC architecture. If so, keep in mind that it's very difficult to maintain the code if you pass the route handlers' objects into the model's methods. An better approach is to implement the model separately from the Dancer DSL, giving it a command-line interface and unit tests. Once that's complete, call the model from the route handlers using data retrieved from the controller using calls like "params". This will make it much easier to identify bugs and make changes down the track - knowing that the impact is limited to the layer in which you're making the change/identifying the bug.
On 1/23/2014 08:47, Andrew Solomon wrote:
When you say "the modules that do the work in my app" I'm assuming you mean the model in an MVC architecture.
Nope. MVC is a bad fit for our app. (...Which is the main reason we rejected Catalyst and Jifty when looking at Perl web frameworks to replace Apache::ASP.) When I say Perl module, I mean a *.pm file. Maybe you prefer to call them them Perl packages, after the "package" keyword? I'm making a distinction between the generated lib/Foo.pm file, which we want to keep as small as possible, and our lib/Foo/*.pm module files, which contain the bulk of our Perl code. If you had to slice our app on MVC lines, the Perl web server code is mostly "C" with essentially no "M" and as little "V" as is practical given the nature of web apps. As browsers get more powerful, we're moving more and more "V" code into the JS layer. But again, MVC isn't a good abstraction for our app. A better description for the Perl layer in our app is "glue," binding the back-end C++ servers to the front-end JS code. Perl still makes great Internet Duct Tape, as far as we're concerned.
Another advantage of creating the app as a standalone app (like a common CPAN package) is that you will be able to use with another framework if Dancer will not be ready when it is ready, so you don't need to invest effort in the web-related part until you'll know that the web framework you want to use is good. Plus that you will be able to create tests and you will be able to add command line scripts easier if you need them. --Octavian ----- Original Message ----- From: Andrew Solomon To: Perl Dancer users mailing list Sent: Thursday, January 23, 2014 5:47 PM Subject: Re: [dancer-users] Confused about types and globals On Thu, Jan 23, 2014 at 2:18 PM, Warren Young <warren@etr-usa.com> wrote: Ideally, I want my top-level module to be as small as possible, doing little more than set up the route handlers, delegating all the real work to other modules. To do that, I need to know where these objects come from, their exact data type, and which package's namespace they live in. Then I'll know how to reference them or pass them around to the modules that do the work in my app. When you say "the modules that do the work in my app" I'm assuming you mean the model in an MVC architecture. If so, keep in mind that it's very difficult to maintain the code if you pass the route handlers' objects into the model's methods. An better approach is to implement the model separately from the Dancer DSL, giving it a command-line interface and unit tests. Once that's complete, call the model from the route handlers using data retrieved from the controller using calls like "params". This will make it much easier to identify bugs and make changes down the track - knowing that the impact is limited to the layer in which you're making the change/identifying the bug. ------------------------------------------------------------------------------ _______________________________________________ dancer-users mailing list dancer-users@dancer.pm http://lists.preshweb.co.uk/mailman/listinfo/dancer-users
participants (5)
-
Andrew Solomon -
David Golden -
Octavian Rasnita -
Warren Young -
Yanick Champoux