Alternative Way To Do Global Variables, using __PACKAGE__ |
In the process of developing a large website I have found it can be a
little onerous at times to use the Request object to pass around
global data. I would like to just create variables like $xxx rather
than typing $req->{xxx} all the time. It may not seem like much, but
after a while your code can start looking a lot more complex because
of all the extra brackets and suchlike. As a typical lazy programmer,
I looked for a way to simplify this. The method I am going to describe should be used with caution, because
it can increase memory useage rather dramatically if you're not
careful. The way I use it, no extra memory is used, but you do need to
be aware of the issues. Basically, you change the way you include files from /base.html , so
that they are included into the same package as /base.html : [- Execute ({inputfile => '*', package => __PACKAGE__}) -] You should only do this with HTML files which are included from
/base.html , not with the files such as subs.html - those files
have to be in their own packages in order for Perl inheritance to
work. You can't use this technique with any files which are accessed
via method calls. So how does this make things better? Well, since all these files now
share the same package, any variables which are created in one of the
files is accessible to any of the other files. This means that if you
create $xxx in /init.html , then you can access $xxx in
/head.html or any other file. This effectively gives you global
variables across all the files which are included from /base.html
into the same package as /base.html . The thing you need to be careful of here is that if one of these files
is included more than once elsewhere on the website, then it will be
seperately compiled for that instance - thus taking up more
memory. This is the big caveat. As a rule, if your files are all just
included once by /base.html , then you should be fine. Note that
you'll also need to change any calls to parent files, for example: /contact/init.html
[- Execute ({inputfile => '../init.html', package => __PACKAGE__}) -] [-
# Do some setup specific to this subdirectory
-] This is ok, since ../init.html will still be compiled into the same
package as the rest of the files included from /base.html , and so
only one version of it will exist in the Embperl cache. Thus memory
usage is not increased. I like this technique because it simplifies the look of my code, which
is important for projects containing complex algorithms. It is not the
"official" way to implement globals though, and should be used with
care.
|