You are viewing a plain text version of this content. The canonical link for it is here.
Posted to embperl@perl.apache.org by Neil Gunton <ne...@nilspace.com> on 2001/02/09 18:02:08 UTC

(possibly stupid) idea for EmbperlObject variables

Hi Gerald,

I had an idea regarding the issue of having variables which are visible
to all pages in any request. Currently we get a Request object passed in
on the stack, which we can set variables in. However I have found this
to be rather inconvenient due to the extra syntax involved with
accessing such variables. For instance instead of $foo we now have
$req->{foo}. As a result I currently include files from base.html into
the same package. This enables me to have simple variables which are
shared between files.

However, there are potential problems with using the same package, and
it also short circuits the inheritance mechanisms. 

Here's the idea: We currently get certain variables made available to
each page, such as %fdat. What if there was an object similar to (but
not the same as) $req, where we could set variables; call it, say,
$global. Then, we have $global passed in on the stack (like $req). But
in addition, we also get all the variables which have been set in
$global set directly in the current package, automatically, like %fdat.

For example, in one page we say $global->{foo} = "hello"; then, in
another (subsequently executed) page we would have a variable called
$foo automatically initialized for us to "hello".

If you then change one of these variables, the change is reflected for
other pages. I don't know if this is technically possible because I am
still a little fuzzy on the details of how Perl manages namespaces and
variable references. But, knowing Perl, it should be possible...

Does this make any sense? It would enable more global variables and make
it easier to code these, while keeping each page in its own package, and
resulting in tidier code (in my opinion). I'm just thinking about the
variables that Embperl currently automatically sets for us - couldn't it
also automatically add references to other variables, based on the
contents of an object like $global?

This is just an idea, perhaps not fully formed, and I have no idea how
hard it would be in practice. Any comments?

TIA

-Neil

Re: (possibly stupid) idea for EmbperlObject variables

Posted by Neil Gunton <ne...@nilspace.com>.
> Not completely understanding what you're up to, I don't know if this
> is useful or not, but here it is anyway, for what it's worth.  Quicker
> to cut and paste this than try and invent it from nothing !

Thanks a lot Jim, I will take a look at this and see how I can use it in
my projects...

Much appreciated

/Neil

Re: (possibly stupid) idea for EmbperlObject variables

Posted by Jim Peters <ji...@aguazul.demon.co.uk>.
Neil Gunton wrote:
> I had an idea regarding the issue of having variables which are visible
> to all pages in any request. Currently we get a Request object passed in
> on the stack, which we can set variables in. However I have found this
> to be rather inconvenient due to the extra syntax involved with
> accessing such variables. For instance instead of $foo we now have
> $req->{foo}. As a result I currently include files from base.html into
> the same package. This enables me to have simple variables which are
> shared between files.

I don't know how useful this is to you (or others), but I'm running
Embperl (not EmbperlObject) from my own Apache handler.  I do all the
session and component handling from there, and use Embperl for
rendering components.  Pretty well all the Embperl .html files start
with:

  [! use Steel::EP !]

This imports a bundle of variables into the namespace, which gives me
access to component-level variables $c{xxx} and session-level
variables $s{user}, and the current component URL $page, amongst other
things.  This is short and convenient enough for me.  Steel::EP
includes a few helper routines as well, but the start is like this,
which is all you'd need to reproduce the variable imports:

  #!/usr/bin/perl -w

  package Steel::EP;
  use strict;
  use Steel::Page ();
  use Apache::Util qw(escape_uri escape_html);
  $^W= 1;
  
  # Importer
  sub import {
      my $my_pkg = shift;         # Should be Steel::EP
      my $pkg = caller(0);        # Should be Embperl target package
  
      no strict;
      #print STDERR "Existing keys in Embperl package `$pkg':\n";
      #print STDERR "  ", join(" ", keys(%{"${pkg}::"})), "\n";
  
      *{"${pkg}::s"}= *Steel::Page::s;
      *{"${pkg}::r"}= *Steel::Page::r;
      *{"${pkg}::c"}= *Steel::Page::c;
      *{"${pkg}::level"}= *Steel::Page::st_level;
      *{"${pkg}::page"}= *Steel::Page::st_page;
      *{"${pkg}::comp"}= *Steel::Page::st_comp;
      *{"${pkg}::dbh"}= *Steel::Page::dbh;
      *{"${pkg}::db"}= *Steel::Page::db;
  }
  
Not completely understanding what you're up to, I don't know if this
is useful or not, but here it is anyway, for what it's worth.  Quicker
to cut and paste this than try and invent it from nothing !

Jim

-- 
 Jim Peters         /             __   |  \              Aguazul
                   /   /| /| )| /| / )||   \
 jim@aguazul.      \  (_|(_|(_|(_| )(_|I   /        www.aguazul.
  demon.co.uk       \    ._)     _/       /          demon.co.uk

Re: (possibly stupid) idea for EmbperlObject variables

Posted by Neil Gunton <ne...@nilspace.com>.
Gerald Richter wrote:
> 
> Neil,
> 
> the main problem with your idea, that I currently have, is in which files
> these globals should be accessable. As I understand you right, you would
> make it accessable from all files which are used in one request, while this
> makes sense, it is not very efficient. Normaly I try to setup all those
> things only once, so any further request doesn't have to do it again. If I
> would resetup those globals (which would be actualy aliases to one global),
> for every request I can simply do this with all files which are handled in
> this request, but if I don't want to resetup it every time, there must be
> some way to tell Embperl, which pages belong together and should share the
> same globals.

Hi Gerald,

I understand your concern... let me first say that I don't really have
strong feelings about this feature yet - I am very open to someone
telling me it's just a bad idea all round. But as for your main point
here, regarding efficiency: The first thing that came into my head is
what we do in EmbperlObject to implement inheritance:

	[! Execute ({isa => '../subs.html'}) !]

This is used to enable a feature which is not required for all pages.
So, how about a similar thing for the sharing of variables. Something
like this:

	[! Execute ({shares => 'global'}) !]

This would tell Embperl that this file should share whatever is in
%global. I don't know if this method would work; I think it would need
to be in [! !] block so that Embperl could set all this up before the
first execute (not too sure about the ordering of events here with
regard to compiling...).

This method, if it is practical, would enable different hashes (e.g.
%global, %foo, %bar) to be set up and the variables set therein to be
shared between different files, on a per-file basis. Each file would
tell Embperl which variable sets it wishes to share (i.e. multiple calls
to Execute() if more than one).

What do you think? Would this work?

Thanks!

-Neil

Re: (possibly stupid) idea for EmbperlObject variables

Posted by Gerald Richter <ri...@ecos.de>.
Neil,

the main problem with your idea, that I currently have, is in which files
these globals should be accessable. As I understand you right, you would
make it accessable from all files which are used in one request, while this
makes sense, it is not very efficient. Normaly I try to setup all those
things only once, so any further request doesn't have to do it again. If I
would resetup those globals (which would be actualy aliases to one global),
for every request I can simply do this with all files which are handled in
this request, but if I don't want to resetup it every time, there must be
some way to tell Embperl, which pages belong together and should share the
same globals.

Gerald

-------------------------------------------------------------
Gerald Richter    ecos electronic communication services gmbh
Internetconnect * Webserver/-design/-datenbanken * Consulting

Post:       Tulpenstrasse 5         D-55276 Dienheim b. Mainz
E-Mail:     richter@ecos.de         Voice:    +49 6133 925131
WWW:        http://www.ecos.de      Fax:      +49 6133 925152
-------------------------------------------------------------

----- Original Message -----
From: "Neil Gunton" <ne...@nilspace.com>
To: <em...@perl.apache.org>
Sent: Friday, February 09, 2001 6:37 PM
Subject: Re: (possibly stupid) idea for EmbperlObject variables


> Gerald Richter wrote:
> >
> > Neil,
> >
> > first of all it would be possible. Because more people already run
across
> > this problem (even without EmbperlObject), I have somewhere in my mind
the
> > idea of an export or share parameter for Execute, something like
> >
> > Execute ({inputfile => '*', export => ['$foo', '@bar']}) ;
> >
> > then $foo and @bar will be exported in the called package. So you can
access
> > them from both packages like a normal global variable.
> >
> > Would this solve your problem, or do you think adding this parameter to
> > every Execute would mean to much overhead for you ?
>
> This is an interesting idea, and it would definitely be useful in some
> circumstances (e.g. where you want to keep strict control over what is
> passed around). But in my case I have a whole set of files which have
> been split up for the purposes of modularity, but they are all
> conceptually part of the same web page; so it is quite possible that one
> page might want to set a variable that is then used by another page. The
> thing is, the first file is not Executing the second file directly -
> they are both included from base.html. So, it would be non-intuitive to
> require base.html to be aware of all variables which need to be shared
> between files.
>
> I think it would be useful to at least have the option of this global
> hash, the contents of which are set as real variables in each page in
> the request. Sure, it's open to abuse and bad programming, but so is a
> lot of stuff in Perl. I am still not too sure if the global hash is the
> best way to go. In a nutshell, what I want to end up with is the ability
> to do something like the following:
>
> /base.html
>
> [- $req = shift; $global = shift; -]
> [- $global->{foo} = "hello" -]
> [- Execute ('one.html') -]
> [- Execute ('two.html')
>
> /one.html
>
> [- $req = shift; $global = shift; -]
> [+ $foo +]
> [- $foo = "goodbye" -]
> [- $global->{bar} = "whatever" -]
>
> /two.html
>
> [+ $foo +]
> [+ $bar +]
>
> Then, the output from this might be something like
>
> hello goodbye whatever
>
> Does this make sense? The main point is that we reference these
> variables just like any other variables. You say this is possible, which
> sounds great. It does give control over what is made global, because
> only variables which are set in %global are passed into subsequent
> files.
>
> On the downside, it is not immediately apparent that these variables are
> global, so again it opens up the potential for obscure bugs. But the
> power and relative elegance of the feature could outweigh this.
>
> I am not really pushing for this, because I am quite happy right now
> with the way I have Embperl set up. But it just occurred to me as a
> potential way to get around the annoying problem of variables which are
> logically global to any given request...
>
> How hard would this be to implement? Any idea?
>
> Comments, flames etc welcomed...
>
> -Neil
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: embperl-unsubscribe@perl.apache.org
> For additional commands, e-mail: embperl-help@perl.apache.org
>
>
>


Re: (possibly stupid) idea for EmbperlObject variables

Posted by Neil Gunton <ne...@nilspace.com>.
Gerald Richter wrote:
> 
> Neil,
> 
> first of all it would be possible. Because more people already run across
> this problem (even without EmbperlObject), I have somewhere in my mind the
> idea of an export or share parameter for Execute, something like
> 
> Execute ({inputfile => '*', export => ['$foo', '@bar']}) ;
> 
> then $foo and @bar will be exported in the called package. So you can access
> them from both packages like a normal global variable.
> 
> Would this solve your problem, or do you think adding this parameter to
> every Execute would mean to much overhead for you ?

This is an interesting idea, and it would definitely be useful in some
circumstances (e.g. where you want to keep strict control over what is
passed around). But in my case I have a whole set of files which have
been split up for the purposes of modularity, but they are all
conceptually part of the same web page; so it is quite possible that one
page might want to set a variable that is then used by another page. The
thing is, the first file is not Executing the second file directly -
they are both included from base.html. So, it would be non-intuitive to
require base.html to be aware of all variables which need to be shared
between files.

I think it would be useful to at least have the option of this global
hash, the contents of which are set as real variables in each page in
the request. Sure, it's open to abuse and bad programming, but so is a
lot of stuff in Perl. I am still not too sure if the global hash is the
best way to go. In a nutshell, what I want to end up with is the ability
to do something like the following:

/base.html

	[- $req = shift; $global = shift; -]
	[- $global->{foo} = "hello" -]
	[- Execute ('one.html') -]
	[- Execute ('two.html')

/one.html

	[- $req = shift; $global = shift; -]
	[+ $foo +]
	[- $foo = "goodbye" -]
	[- $global->{bar} = "whatever" -]

/two.html

	[+ $foo +]
	[+ $bar +]

Then, the output from this might be something like

	hello goodbye whatever

Does this make sense? The main point is that we reference these
variables just like any other variables. You say this is possible, which
sounds great. It does give control over what is made global, because
only variables which are set in %global are passed into subsequent
files.

On the downside, it is not immediately apparent that these variables are
global, so again it opens up the potential for obscure bugs. But the
power and relative elegance of the feature could outweigh this. 

I am not really pushing for this, because I am quite happy right now
with the way I have Embperl set up. But it just occurred to me as a
potential way to get around the annoying problem of variables which are
logically global to any given request...

How hard would this be to implement? Any idea?

Comments, flames etc welcomed...

-Neil