[22602] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 4823 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Apr 7 03:05:43 2003

Date: Mon, 7 Apr 2003 00:05:07 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Mon, 7 Apr 2003     Volume: 10 Number: 4823

Today's topics:
    Re: <script language=PerlScript> for Mozilla initiative <founder@pege.org>
    Re: <script language=PerlScript> for Mozilla initiative <me@privacy.net>
    Re: <script language=PerlScript> for Mozilla initiative <tony_curtis32@yahoo.com>
    Re: <script language=PerlScript> for Mozilla initiative <flavell@mail.cern.ch>
    Re: <script language=PerlScript> for Mozilla initiative <founder@pege.org>
        ActiveX <ganchrow@nospam.com>
    Re: Addition in substitution (Philip Lees)
        Advt: LinuxCertified announces Perl class in San Jose (info@linuxcertified.com)
        cgi interface <cheese0@hotmail.com>
    Re: Checkbox  Values Into a DB <jessicak@nac.net>
    Re: IO::FILE undedined (M.J.T. Guy)
    Re: looking for duplicates <jkeen@concentric.net>
    Re: LWP post problem (Chacrint Charinthorn)
        regular expression problem <m9l3@interchange.ubc.ca>
    Re: regular expression problem <jurgenex@hotmail.com>
    Re: trying to do date parsing <jkeen@concentric.net>
    Re: Which is better - hashes or subroutines <mbear@uq.net.au>
    Re: Which is better - hashes or subroutines <tassilo.parseval@rwth-aachen.de>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Mon, 7 Apr 2003 00:19:09 +0200
From: =?iso-8859-1?Q?Roland_M=F6sl?= <founder@pege.org>
Subject: Re: <script language=PerlScript> for Mozilla initiative
Message-Id: <3e90a949$0$41844$91cee783@newsreader02.highway.telekom.at>

> > I am talking with somebody complete uninformed about PerlScript
> >
> > And I make my living with an application programed in PerlScript.
> >
> > But I thought it would be nice to use Linux.
> > So I thought to start an initiative to implement this possibility in
> > Mozilla.
> >
> > But seems Mozilla people are to arrogant for a nice proposal
>
>     Or perhaps you are too arrogant to change your ways to using
> "standard" Web languages (HTML + JavaScript) rather than using
> vendor-specific tie-ins?

JavaScript can not write to files

>     Sending Perl code for a Web browser to run sounds like a potential
> security problem

So You just proofed again how uninformed You are.

PerlScript can by default of MSIE only be executed on the own machine.

It's practicall to write software in PerlScript using the browser as GUI


--
Roland Mösl
http://www.pege.org Clear targets for a confused civilization
http://web-design-suite.com Web Design starts at the search engine



------------------------------

Date: Mon, 7 Apr 2003 08:29:06 +1000
From: "Tintin" <me@privacy.net>
Subject: Re: <script language=PerlScript> for Mozilla initiative
Message-Id: <b6q9nk$81m8h$1@ID-172104.news.dfncis.de>


"Roland Mösl" <founder@pege.org> wrote in message
news:3e90a949$0$41844$91cee783@newsreader02.highway.telekom.at...
> > > I am talking with somebody complete uninformed about PerlScript
> > >
> > > And I make my living with an application programed in PerlScript.
> > >
> > > But I thought it would be nice to use Linux.
> > > So I thought to start an initiative to implement this possibility in
> > > Mozilla.
> > >
> > > But seems Mozilla people are to arrogant for a nice proposal
> >
> >     Or perhaps you are too arrogant to change your ways to using
> > "standard" Web languages (HTML + JavaScript) rather than using
> > vendor-specific tie-ins?
>
> JavaScript can not write to files

Server side JavaScript can.




------------------------------

Date: Sun, 06 Apr 2003 19:52:52 -0500
From: Tony Curtis <tony_curtis32@yahoo.com>
Subject: Re: <script language=PerlScript> for Mozilla initiative
Message-Id: <87y92nku1n.fsf@limey.hpcc.uh.edu>

>> On Mon, 7 Apr 2003 00:19:09 +0200,
>> Roland Mösl <founder@pege.org> said:

> JavaScript can not write to files

There's a good reason for that.

>> Sending Perl code for a Web browser to run sounds like
>> a potential security problem

> So You just proofed again how uninformed You are.

> PerlScript can by default of MSIE only be executed on
> the own machine.

Oh, that's *really* secure, *oder*?


------------------------------

Date: Mon, 7 Apr 2003 02:24:55 +0200
From: "Alan J. Flavell" <flavell@mail.cern.ch>
Subject: Re: <script language=PerlScript> for Mozilla initiative
Message-Id: <Pine.LNX.4.53.0304070143340.17202@lxplus005.cern.ch>

On Sun, Apr 6, Roland Mösl inscribed on the eternal scroll:

> > You can _make_ them with HTML; but they don't _do_ anything without a
> > shedload more than mere HTML markup.  Such as server-side scripts...
>
> Seems You do not know what PerlScript means

OK, that's it: I knew you wanted to go into the killfile, I was only
verifying my suspicions.

Sure I know that Perlscript is, and that most WWW clients don't have
it, nor that Operating System Component thing either.  I also know
what "such as" means, which you just demonstrated you do not.

> <script language=PerlScript>
>
> # You do not need server side scripts

_You_ might not: but out in the real world, most clients do.

> # You can put all the scripts here
>
> </script>
>
> But that's only possible in Microsoft Internet Explorer.

You certainly won't be executing your Perl scripts on _my_ copy of
MSIE, even on the infrequent occasions when I run it instead of a WWW
browser.

Anyhow, that wasn't the point.  _You_ claimed to be talking about
HTML - not about Perlscript or any other kind of client-side script.

> Any it seems You do not want to change,

How little you have grasped.  But not to worry.  I'm sure you're
making a good living out of it.

bye.


------------------------------

Date: Mon, 7 Apr 2003 07:54:14 +0200
From: =?iso-8859-1?Q?Roland_M=F6sl?= <founder@pege.org>
Subject: Re: <script language=PerlScript> for Mozilla initiative
Message-Id: <3e9114c5$0$32042$91cee783@newsreader01.highway.telekom.at>

"Alan J. Flavell" <flavell@mail.cern.ch> wrote in message
news:Pine.LNX.4.53.0304070143340.17202@lxplus005.cern.ch...
> On Sun, Apr 6, Roland Mösl inscribed on the eternal scroll:
>
> > > You can _make_ them with HTML; but they don't _do_ anything without a
> > > shedload more than mere HTML markup.  Such as server-side scripts...
> >
> > Seems You do not know what PerlScript means
>
> OK, that's it: I knew you wanted to go into the killfile, I was only
> verifying my suspicions.

Easy solution for new ideas.

You know the 3 monkeys ?

> Sure I know that Perlscript is, and that most WWW clients don't have
> it, nor that Operating System Component thing either.  I also know
> what "such as" means, which you just demonstrated you do not.
>
> > <script language=PerlScript>
> >
> > # You do not need server side scripts
>
> _You_ might not: but out in the real world, most clients do.
>
> > # You can put all the scripts here
> >
> > </script>
> >
> > But that's only possible in Microsoft Internet Explorer.
>
> You certainly won't be executing your Perl scripts on _my_ copy of
> MSIE, even on the infrequent occasions when I run it instead of a WWW
> browser.

If You would be able to read before You flame,
You would maybe been able, that this is for software development.

It's called reusing browser technology.
And You would be only able to run it on Your computer after
You have paid for it


--
Roland Mösl
http://www.pege.org Clear targets for a confused civilization
http://web-design-suite.com Web Design starts at the search engine



------------------------------

Date: Mon, 07 Apr 2003 05:08:23 GMT
From: "Ganchrow Harris Peck" <ganchrow@nospam.com>
Subject: ActiveX
Message-Id: <bJ7ka.3327$py2.2464@twister.nyc.rr.com>

I have a set of ActiveX DLL's and OCX's which provide the only interface to
a third-party server.

I also have a set of Perl scripts which, in a time-intensive event-driven
environment, would both consume data from and produce data for the
third-party server.

Short of rewriting my code in VC++ (beyond the scope of my abilities) or VB
(beyond the scope of VB's abilities) can anyone think of a way to hook in
such scripts to the server interface?

Apparently, I will not be able to use Win32::OLE as according to its
documentation "OLE events and OCX's are currently not supported."


--
To e-mail me directly, please change "nospam" in my e-mail address to
"yahoo".

Thanks,
Ganchrow




------------------------------

Date: Mon, 07 Apr 2003 06:37:22 GMT
From: pjlees@ics.forthcomingevents.gr (Philip Lees)
Subject: Re: Addition in substitution
Message-Id: <3e911bf4.236189000@news.grnet.gr>

On Sat, 05 Apr 2003 20:03:36 GMT, "Blakis" <brflaming@yahoo.com>
wrote:

>I'm trying to update the version number in a bunch of Java files using
>Perl. The Java files all have a line similar to the following:
>
> * @version 1.0.4
>
>I want my Perl script to increment the last number by one. 

I was wondering whether Perl could do this automagically, but it seems
that while

my $var = 'version104';
$var++;
print "$var\n";

does what I would expect (i.e. print version105),

my $var = 'version_104';
$var++;
print "$var\n";

or other more complex variations, do not. Could somebody please
explain why?

Phil
-- 
Ignore coming events if you wish to send me e-mail


------------------------------

Date: 6 Apr 2003 15:23:55 -0700
From: info@linuxcertified.com (info@linuxcertified.com)
Subject: Advt: LinuxCertified announces Perl class in San Jose
Message-Id: <d8b08058.0304061423.19a2bda3@posting.google.com>

San Jose, CA March 31, 2003 

LinuxCertified, Inc. (www.linuxcertified.com) today announced addition
of a new class, Perl 101, to its repertoire of fast-paced classes on
Open Source technologies. The first class will be taught on April 19,
in San Francisco-Bay Area.

This day long workshop features a practical and extensive introduction
to Perl, with practical lab exercises. The class covers beginning
through intermediate Perl language skills, such as manipulating files
and directories, regular expressions, Perl data structures, good
programming practices, and more. Both developers and administrators
will benefit immediately from this class, by being able to apply
valuable Perl expertise in their environment.

"Today Perl is the de facto standard for server side components of
Internet applications," said Chander Kant, President of
LinuxCertified. "This addition to our classes further strengthens our
portfolio in bringing the best of Open-Source technology training for
todays IT needs."

This new class maintains and builds on the high-quality standards
created by other classes at LinuxCertified. The details of the class
can be seen at:

http://www.linuxcertified.com/perltraining.html 

About LinuxCertified, Inc. The mission of LinuxCertified, Inc is to
help our clients benefit from significant savings of effectively using
Linux and Open-Source software in their IT infrastructure.
Our core offerings are: 

- Linux trained and certified professionals
- Implementation and development services using Open-Source software
- LinuxCertified products providing industrys best ROI 

For Details Contact:
Rajesh Goyal
LinuxCertified, Inc.
408-314-6700
http://www.linuxcertified.com/


------------------------------

Date: Mon, 7 Apr 2003 14:13:25 +1000
From: "cheesypuffs" <cheese0@hotmail.com>
Subject: cgi interface
Message-Id: <b6qtt6$ng6$1@perki.connect.com.au>

I would like to create a simple interface to change firewall rules (ipf) on
my firewall.    Im a below average to average user of perl, that just needs
a pointer in the right direction to start learning how to get this done.
Would a perl CGI interface be a good development environment to do this in?
and can someone point me in the right direction for some tutorials.

thanxs




------------------------------

Date: Mon, 07 Apr 2003 10:33:06 -0400
From: Jessica <jessicak@nac.net>
Subject: Re: Checkbox  Values Into a DB
Message-Id: <3e90e363_2@nntp2.nac.net>

Oops

First post to Newsgroups, my bad.

Here is the checkbox from the form:

<form ACTION="http://a.org/cgi-bin/member/add.pl" METHOD="POST">

<p>5. Below is the list of committees that we created.  Please check 
those you are interested in participating in.  What other committees 
would you like to see?</p>

<p>
<input TYPE="checkbox" NAME="committee_interest[]" VALUE="Message">Web 
Message Board<br>
<input TYPE="checkbox" NAME="committee_interest[]" 
VALUE="Sunshine">Sunshine Club (Birthdays)<br>
<input TYPE="checkbox" NAME="committee_interest[]" 
VALUE="Membership">Membership (keep track of membership list)<br>
<input TYPE="checkbox" NAME="committee_interest[]" 
VALUE="Social">Contact for Social Calendar<br>
</p>

I have tried it without the [] and with [] as I've seen in php examples 
but it doesnt help, I still only get one value put in. Here is the perl 
code:

#!/usr/local/bin/perl
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use DBI;

$q = new CGI;
$dbh = 
DBI->connect("DBI:mysql:member:localhost","correct","thecorrectpasssword"); 



#values passed from a_survey.htm and put into variables
$first_name = $q->param('first_name');  #Textfield first_name
$first_name = fix_string($first_name);

$last_name = $q->param('last_name');  #Textfield last_name
$last_name = fix_string($last_name);

$addr_1 = $q->param('addr_1');  #Textfield addr_1
$addr_1 = fix_string($addr_1);

$addr_2 = $q->param('addr_2');  #Textfield addr_2
$addr_2 = fix_string($addr_2);

$city = $q->param('city');         #textfield city
$city = fix_string($city);

$state = $q->param('state');   #textfield state
$state = fix_string($state);

$zip = $q->param('zip');    #textfield zip
$zip = fix_string($zip);

$phone = $q->param('phone');     #textfield phone
$phone = fix_string($phone);

$email = $q->param('email');         #textfield email
$email = fix_string($email);

$birthday = $q->param('birthday');       #textfield birthday
$birthday = fix_string($birthday);

$find = $q->param('find'); #radio button find
$find = fix_string($find);

$event_place = $q->param('event_place');       #textfield event_place
$event_place = fix_string($event_place);


$project_interest = $q->param('project_interest');       #textfield 
project_interest
$project_interest = fix_string($project_interest);

$host_project = $q->param('host_project'); #radio button host_project
$host_project = fix_string($host_project);

$social_interest = $q->param('social_interest');       #textfield 
social_interest
$social_interest = fix_string($social_interest);

$host_social = $q->param('host_social'); #radio button host_social
$host_social = fix_string($host_social);

$lead_committee = $q->param('lead_committee');       #textfield 
lead_committee
$lead_committee = fix_string($lead_committee);

@committee_interest = $q->param('committee_interest[]'); #checkbox 
button committee_interest
###$committee_interest = fix_string($committee_interest);

$other_interest = $q->param('other_interest');       #textfield 
other_interest
$other_interest = fix_string($other_interest);


#insert items into database

    $sth=$dbh->prepare("
    INSERT INTO membership
    VALUES (0, '$first_name', '$last_name', '$addr_1', '$addr_2', 
'$city', '$state', '$phone', '$email', '$birthday', '$find', 
'$event_place', '$project_interest', '$host_project', 
'$social_interest', '$host_social', '$lead_committee', 
'@committee_interest', '$other_interest')
    ");
    $sth->execute;
    $sth->finish;

#disconnect from the database
$dbh->disconnect;


print "Content-type: text/html\n\n";
print "<html>\n <head>\n";
print "<title>Membership to A Added</title>\n";
print "</head>\n <body bgcolor = \"\#FFFFFF\">";
print "<table border=\"0\" width=\"80%\" cellspacing=\"0\" 
cellpadding=\"0\" align=\"center\">\n<tr>\n<td align=\"center\">";
print "<h2>Your Membership to A has added to the 
database</h2>\n</td>\n</tr>";
print "<tr>\n<td align=\"center\">";
print "</td>\n</tr>\n";
print "<tr>\n<td align=\"center\">";
print "<a href=\"../../index.htm\">Back to the main Site</a>\n</td>\n</tr>";
print "<tr>\n<td align=\"center\">";
print "<a href=\"http://groups.yahoo.com\">Sign up for our e-mail 
list</a>\n</td>\n</tr>";
print "\n</table>";
print $q->end_html;


sub fix_string()
{
         my($loc) = @_;
         $loc =~ s/['"\\]/\\$&/g;
         return $loc;
}

Hope this clears things up but it's still not wanting to work.

Jessica

William Alexander Segraves wrote:
> "Jessica" <jessicak@nac.net> wrote in message
> news:3e8f582e$1_1@nntp2.nac.net...
> 
>>Hi,
>>
>>I'm using Perl to input results of a form into a MySQL database.
>>
>>I'm using the CGI module
>>
>>The problem is with the checkbox's (Box1 name="interests"
>>value="hiking", Box2 name="interests" value="skiing", Box3
>>name="interests" value="swiming" etc...
>>
>>Everything else on the form is working but with the checkbox values I'm
>>only getting the first checked value put into the DB. I know that this
>>probably has something to do with arrays but I'm clueless as what to do
>>about looping through it to get a string to put into a variable (with a
>>space between each value) that I can put into the db.
>>
>>Any one have a snippet of code and could you give a brief description of
>>what it's doing??
> 
> 
> Jessica, you haven't shown us your code; but ...
> 
> In CGI.htm, search for "A Simple Example" to see how CGI.pm treats multiple
> values, e.g., from a Checkbox.
> 
>  print join(", ",param('words'));
> 
> returns comma (and space) - separated value(s) of 'words'. If you want
> space-separated, just delete the comma (in quotes in the join statement).
> 
> Good luck.
> 
> Bill Segraves
> 
> 
> 



------------------------------

Date: 6 Apr 2003 23:37:53 GMT
From: mjtg@cus.cam.ac.uk (M.J.T. Guy)
Subject: Re: IO::FILE undedined
Message-Id: <b6qdoh$s7v$1@pegasus.csx.cam.ac.uk>

Anno Siegel <anno4000@lublin.zrz.tu-berlin.de> wrote:
>Ali <hazal@web.de> wrote in comp.lang.perl.misc:
>> Can't use an undefined value as a symbol reference at "script.pl" line
>> 41.
>
>Looks like IO::File->new failed to deliver an object, for whatever
>reason.

"Always check the return values from system calls."    But the reason
certainly isn't lack of an installed IO::File.

>IO::File was only delivered with 5.8.0.  It should work with earlier
>versions (> 5.006_001) if you install it.

Rubbish.    IO::File has been in the core since perl5.004.
And if IO::File isn't present, the program would crash, not fail quietly.


Mike Guy


------------------------------

Date: 07 Apr 2003 02:46:44 GMT
From: "James E Keenan" <jkeen@concentric.net>
Subject: Re: looking for duplicates
Message-Id: <b6qoqk$ski@dispatch.concentric.net>


"Benjamin Goldberg" <goldbb2@earthlink.net> wrote in message
news:3E8BBC28.FB3F88CB@earthlink.net...
> James E Keenan wrote:
> [snip]
> > Something like this?
> >
> > my (%seen);
> > while (<DATA>) {
> >  next unless (/\d+/);
> >  my @nums = $_ =~ /(\d+)/g;
> >  foreach my $n (@nums) {
> >   $seen{$n}++;
> >  }
> > }
>
> I prefer shorter code like:
>
>    my %seen;
>    while( <DATA> ) {
>       ++$_ for @seen{/\d+/g};
>    }
>
Interesting.  Why '++$_' rather than '$_++'?

> The 'cmp' operator is a stringwise comparison, and is the default
> comparator that sort uses.  I suspect that you meant to write '<=>',
> which does numeric comparison, instead.
>
Yes, I did intend numeric comparison.  I was trying to see what I could cook
up quickly.




------------------------------

Date: 6 Apr 2003 17:19:37 -0700
From: chacrint@hotmail.com (Chacrint Charinthorn)
Subject: Re: LWP post problem
Message-Id: <bfe227db.0304061619.58089e@posting.google.com>

> maybe we'd better see a _small_ exceprt of the pertinent part of your 
> code...

Below is my code:
---------------------------------

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
$ua = LWP::UserAgent->new('Poster/1.0 ');
$ua->agent('Poster/1.0');
BEGIN { $LWP::DebugFile::outpath = './tmp/' }
use LWP::DebugFile ('+');
 .
 .
 .
  $count=1;

  while ($count <= $maxnum) {

    my $req = POST $posturl,
      [
        refno => $refno,
        snum => $snum,
        dservice => $dservice,
        $namediff => $strdiff,
        typemobile => $typemobile
      ];

    $content = $ua->request($req)->as_string;

    foreach (split(/\n/,$content))
    {
      $_ =~ s/\s//g; # To eliminate white spaces
      if ($_ eq 'Status=0') {
        print("Posted to $snum\_$refno -$count- $tas_tmstamp\n");
        $status = $_;
        &write_log_file;
        exit;
      }


------------------------------

Date: Sun, 6 Apr 2003 21:10:10 -0700
From: "Rong" <m9l3@interchange.ubc.ca>
Subject: regular expression problem
Message-Id: <1049688569.769487@texada.ugrad.cs.ubc.ca>

Suppose a scalar $str contains:
<comment begin>
<1><2>
<comment end>
Hello
<comment begin>
<3><4>
<comment end>
<comment begin>
<1><2>
<comment end>

Can anybody come up with a regular expression that can replace ONLY first
    <comment begin>
    <1><2>
    <comment end>
block with space?
The regular expression I currently get will replace all 3 block. It seems
that
regular expression will try to match as much string as possible.




------------------------------

Date: Mon, 07 Apr 2003 04:14:47 GMT
From: "Jürgen Exner" <jurgenex@hotmail.com>
Subject: Re: regular expression problem
Message-Id: <XW6ka.5055$kr2.2919@nwrddc04.gnilink.net>

Rong wrote:
> Suppose a scalar $str contains:
[...]
> Can anybody come up with a regular expression that can replace ONLY
>     first <comment begin>
>     <1><2>
>     <comment end>
> block with space?
> The regular expression I currently get will replace all 3 block. It
> seems that
> regular expression will try to match as much string as possible.

Reread "perldoc perlre" and check for "greedy".

jue




------------------------------

Date: 07 Apr 2003 02:46:45 GMT
From: "James E Keenan" <jkeen@concentric.net>
Subject: Re: trying to do date parsing
Message-Id: <b6qoql$skj@dispatch.concentric.net>


"Eric Osman" <ericosman@rcn.com> wrote in message
news:3E906DE0.8080306@rcn.com...
>
> Hi,
>
> I'm trying to scan a large digest of emails with perl and parse the
> dates, and I'm hoping one of you readers can help me out here.
>
> The digest is a bunch of concatenated emails with headers looking
> sort of like this:
>
> Date: Sun, 30 Mar 2003 10:30:34 -0800 (PST)
> From: someone@somewhere.com
> To: someoneelse@somewhereelse.com
> Subject: some sort of subject
>
>
> The part I'm focussing on is the date line.
>
> Because the headers like the above SOMETIMES indicate a new email
> message and sometimes are actually a message forwarded within
> another message, I wanted to parse the dates.
>
> Then, if I detect a date that isn't monotonically increasing with the
> others, I can assume that that header is a forwarded message within
> another message.
>
> So far I've found DATE::PARSE which contains
>
>                  strptime(DATE [, ZONE])
>
> to which I can feed
>
>                  Sun, 30 Mar 2003 10:30:34 -0800 (PST)
>
> and it will return and array of
>
>                 ($ss,$mm,$hh,$day,$month,$year,$zone)
>
> I've also found TIME::LOCAL which contains
>
>                  timelocal($sec,$min,$hour,$mday,$mon,$year)
>
> to convert into a local arithmetic time value.
>
Have you checked out Date::Calc?  While I can't say off the top of my head
whether it solves your problem, it solves so many others that it's worth a
look.




------------------------------

Date: Mon, 07 Apr 2003 13:36:20 +1000
From: Matthew Braid <mbear@uq.net.au>
Subject: Re: Which is better - hashes or subroutines
Message-Id: <b6qrnk$4r7$1@bunyip.cc.uq.edu.au>

This is a multi-part message in MIME format.
--------------000809030501040806010603
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi all,

While this has definitely spawned some interesting stuff, it's not quite 
what I had in mind.

The idea of creating new subs on the fly is good for speeding up 
repetitive calls to the same phrase, but unless I copy the data from the 
original hash (using up twice the memory) people can still do something 
like:

$language->{Phrase} = 'NOT THE ORIGINAL TEXT';

and suddenly:

$language->Phrase;

returns 'NOT THE ORIGINAL TEXT', which from a OO standpoint is bad (yes, 
I know perl is missing some of the important parts of OO, especially 
encapsulation and private stuff). But then again, maybe this uses less 
memory/is faster/some other good thing. I don't know. That's what I'm 
asking.

What I was looking for are different methods of storage on the first 
parse of the language file. What are the pros/cons of storage into a 
hash and use of AUTOLOAD over creating closure subroutines or something 
I haven't thought of?

Anyway, attached is a sanitised (this is work stuff so I had to clean it 
- should still be in working order though) version of my code. To make 
it work, copy it to a directory by itself along with the test.pl file, 
create a directory named .languages underneath that (sorry, UNIXish 
only) and copy the 'example-language' file into .languages. Then do a 
'perl test.pl'.

BTW - what are the rules of perl inlining code? Is there a way of 
telling perl to do something inline? (I'm remembering 'pragma inline' in 
Ada...)

MB


--------------000809030501040806010603
Content-Type: text/plain;
 name="Language.pm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Language.pm"

package Language;

# This package is for the loading of language packs.
# Used like:
# use Language;
# my $lang = Language->load(Pack::age, language, section, section...)

# Language will then search @INC for the file
# Pack/age/.languages/language (note language is lower case!)
# and load the sections within it so that calls like:
# $lang->Name
# will return Pack::age's Language string for Section Name.

# Language files look like: (without the #'s):
# [SectionName]
# BorderString BDS
#
# Key1 BDSSTRING1BDE
# Key2BDSSTRING2BDE
# Key3 BDSSTR
# ING3BDE
#
# The BorderString (BDS and BDE) is the character sequence to delimit value
# strings.
# Instead of BorderString, you can have BorderStringStart and BorderStringEnd
# in a similar form (good for parenthesis)
# The value (STRING1 and STRING2 in this case) is taken as a literal.

use strict;
use vars qw/$AUTOLOAD/;
require IO::File;

my $Error = '';
my $Lno = 1; # Line number tracking is still broken - must fix :)
my $SectHeader = qr/^\s*\[([A-Za-z0-9\s_]+)\]\s*\z/;
my $BString = qr/^BorderString\s+(\S+)\s*\z/;
my $BSStart = qr/^BorderStringStart\s+(\S+)\s*\z/;
my $BSEnd = qr/^BorderStringEnd\s+(\S+)\s*\z/;
my $Ignore = qr/(?:^\s*\#)|(?:^\s*\z)/;

sub load {
  my $class = shift;
  my ($pack, $lang, @sects) = @_;
  if (not defined $pack or not defined $lang or not scalar @sects) {
    die "Package, Language and Section must be supplied!";
  }
  $class = (ref($class) or $class or __PACKAGE__);
  return bless({}, $class)->_initialise($pack, $lang, @sects);
}

sub _initialise {
  my $self = shift;
  my ($pack, $lang, @sects) = @_;
  my $loadfile = $self->_find_language_file($pack, $lang);
  die "Could not find specified language file" if not defined $loadfile;
  die "Could not load language file - $Error"
    if not $self->_load($loadfile, @sects);
  return $self;
}

sub _find_language_file {
  my $self = shift;
  my ($pack, $lang) = @_;
  $pack =~ s/::/\//g;
  $lang = lc($lang);
  my $lookfor = "$pack/.languages/$lang";
  for my $path (@INC) {
    my $match = "$path/$lookfor";
    if (-e $match and -r $match and not -d $match) {
      # Found one!
      return $match;
    }
  }
  return undef;
}

sub _load {
  my $self = shift;
  my ($file, @sects) = @_;

  my $fh = IO::File->new("<$file");
  if (not defined $fh) {
    $Error = "Could not open language file - $!";
    return 0;
  }
  $Lno = 1;
  while (defined(my $line = <$fh>)) {
    next if $line =~ $Ignore;
    if ($line !~ $SectHeader) {
      $Error = "Data outside of section tags at line $Lno";
      return 0;
    }
    my $sectname = $1;
    $sectname = undef if not scalar grep {$_ eq $sectname} @sects;
    return 0 if not $self->_parse_section($fh, $sectname);
  } continue {
    $Lno++;
  }
  $fh->close;
}

sub _parse_section {
  my $self = shift;
  my ($fh, $sectname) = @_;
  
  return $self->_skip_section($fh) if not defined $sectname;
  # First line defines the 'border string' (no whitespace)
  my ($bds, $bde);

  while (defined(my $line = <$fh>)) {
    chomp $line;
    $Lno++;
    next if $line =~ $Ignore;
    if ($line =~ $BString) {
      $bds = $bde = $1;
    } elsif ($line =~ $BSStart) {
      $bds = $1;
    } elsif ($line =~ $BSEnd) {
      $bde = $1;
    } else {
      $Error = "Data before end of String Border declaration at line $Lno";
      return 0;
    }
    last if defined $bds and defined $bde;
  }
  if (not defined $bds or not defined $bde) {
    $Error = "String Borders not defined for section $sectname near line $Lno";
    return 0;
  }
  
  # all lines after that are NAME BDSVALUEBDE
  # NAME has no whitespace, neither does BDS/BDE.
  my $loc = tell($fh);
  while (defined(my $line = <$fh>)) {
    chomp $line;
    $Lno++;
    next if $line =~ $Ignore;
    if ($line =~ $SectHeader) {
      seek($fh, $loc, 0);
      last;
    }
    if ($line !~ /^\s*([^\s]+)\s*\Q$bds\E(.*)\z/) {
      $Error = "Bad data at line $Lno";
      return 0;
    }
    my ($name, $val) = ($1, $2);
    if ($val =~ /\Q$bde\E\s*\z/) {
      $val =~ s/\Q$bde\E\s*\z//;
    } else {
      my $rest = $self->_get_multiline($fh, $bde);
      return 0 if not defined $rest;
      $val .= $rest;
    }
    # Skip taint checking globally for the time being <- later, only for files
    # owned by $<, not writable by others or group
    $val =~ /^(.*)\z/sm;
    $val = $1;
    $self->{Language}->{$name} = $val;
    $loc = tell($fh);
  }
  return 1;
}

sub _skip_section {
  my $self = shift;
  my ($fh) = @_;
  
  my $loc = tell($fh);
  while (defined(my $line = <$fh>)) {
    chomp $line;
    # Skip will also skip over Border String errors!
    if ($line =~ $SectHeader) {
      seek($fh, $loc, 0);
      $Lno--;
      return 1;
    }
    $loc = tell($fh);
    $Lno++;
  }
  return 1;
}

sub _get_multiline {
  my $self = shift;
  my ($fh, $bde) = @_;
  
  my $val = '';
  my $start = $Lno;
  while (defined(my $line = <$fh>)) {
    chomp $line;
    if ($line =~ /\Q$bde\E\s*\z/) {
      # Last line!
      $line =~ s/\Q$bde\E\s*\z//;
      $val .= "\n$line";
      return $val;
    } else {
      # Another line
      $val .= "\n$line";
    }
    $Lno++;
  }
  # Uh-oh - no close found!
  $Error = "Unexpected EOF in language file - may be runaway text starting on line $start";
  return undef;
}

sub AUTOLOAD {
  my $self = shift;
  my $phrase = $AUTOLOAD;
  $phrase =~ s/^.*:://;
  return if $phrase eq 'DESTROY';
  if (exists $self->{Language}->{$phrase}) {
    return $self->{Language}->{$phrase};
  }
  die "Unknown word or phrase: $phrase\n";
}

1;
__END__

--------------000809030501040806010603
Content-Type: text/plain;
 name="example-language"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="example-language"

# Example Language File

[GUI]
BorderStringStart {
BorderStringEnd }
SaveButton{Save}
SaveQuitButton{Save and Quit}

[TEXT]
BorderStringStart {
BorderStringEnd }
LongMultiLineTxt{This text goes over multiple
lines. See?
}

[COMLINE]
BorderString :
ReadOnly:-r:
File:-f:

--------------000809030501040806010603
Content-Type: text/plain;
 name="test.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="test.pl"

use lib ".";
require Language;
my $l = Language->load("", qw/example-language GUI TEXT COMLINE/);
print "TEXT FOR PHRASE 'LongMultiLineTxt' IS ", $l->LongMultiLineTxt, "\n";

--------------000809030501040806010603--



------------------------------

Date: 7 Apr 2003 06:11:10 GMT
From: "Tassilo v. Parseval" <tassilo.parseval@rwth-aachen.de>
Subject: Re: Which is better - hashes or subroutines
Message-Id: <b6r4pu$4rp$1@nets3.rz.RWTH-Aachen.DE>

Also sprach Matthew Braid:

> While this has definitely spawned some interesting stuff, it's not quite 
> what I had in mind.
> 
> The idea of creating new subs on the fly is good for speeding up 
> repetitive calls to the same phrase, but unless I copy the data from the 
> original hash (using up twice the memory) people can still do something 
> like:
> 
> $language->{Phrase} = 'NOT THE ORIGINAL TEXT';
> 
> and suddenly:
> 
> $language->Phrase;
> 
> returns 'NOT THE ORIGINAL TEXT', which from a OO standpoint is bad (yes, 
> I know perl is missing some of the important parts of OO, especially 
> encapsulation and private stuff). But then again, maybe this uses less 
> memory/is faster/some other good thing. I don't know. That's what I'm 
> asking.

While Perl does not have a standard a way of making data private (think of
C++'s 'private'), there are other ways to achieve the same. Some of them
provide even stronger encapsulation than most other languages.

> What I was looking for are different methods of storage on the first 
> parse of the language file. What are the pros/cons of storage into a 
> hash and use of AUTOLOAD over creating closure subroutines or something 
> I haven't thought of?

For your scenario, a hash should always be the primary data structure,
just because it's conventient and appropriate. I know of at least three
ways to protect your hash from unauthorized access: through closures, by
using a restricted hash or through some tie() mechanism. Whether you use
AUTOLOAD or not is merely a matter of how you'd like to access the data.

The simplest way is using a closure. If you make the hash to store the
data a lexical variable in your module, it can't be accessed from
outside but only from those methods that happen to be within the same
scope. This however hash the drawback that the hash is static: Each
object shares the same hash which might not be acceptable for you.
Here's a small example of how to attached a protected hash to each
instance of an object:

    package Closure;

    sub new {
        my $class = shift;
        my $self = bless { } => $class;
        $self->create_closures;
        $self->store(shift);
        return $self;
    }

    sub create_closures {
        my $self = shift;
        {
            my %hash;
            $self->{ store } = sub {
                my ($key, $val) = @_;
                $hash{ $key } = $val;
            };
            $self->{ get } = sub {
                $hash{ +shift };
            };
        }
    }

    sub store {
        my ($self, $key, $val) = @_;
        $self->{ store }->($key, $val);
    }

    sub get {
        my ($self, $val) = @_;
        $self->{ get }->($val);
    }

Now everyone can add data into %hash only by issuing the store() method.
To prevent that the 'wrong people' call store and add whatever to the
hash, you could add a check for caller():

    sub store {
        my ($self, $key, $val) = @_;
        
        my ($pkg) = caller;
        die "Forbidden!" if $pkg->isa("Closure");
        ...
    }

Use 'caller EXPR' if you need even finer control. The above would
implement something on the level of 'protected': Sub-classes of your
class are allowed to call store(), anything else not.

> Anyway, attached is a sanitised (this is work stuff so I had to clean it 
> - should still be in working order though) version of my code. To make 
> it work, copy it to a directory by itself along with the test.pl file, 
> create a directory named .languages underneath that (sorry, UNIXish 
> only) and copy the 'example-language' file into .languages. Then do a 
> 'perl test.pl'.

I had a quick glance at it. It shouldn't be too hard to add means of
protection to your class. The above should be flexible enough to
implement whatever security model you want. Once you have set up the
basic infrastructure (creating the closures, get() and set() method to
work on them), you can add the necessary calls to _parse_section() to
populate the closed hash. Do the same to access it in AUTOLOAD. You can
still use it to compile the accessor methods on the fly, if you want.

> BTW - what are the rules of perl inlining code? Is there a way of 
> telling perl to do something inline? (I'm remembering 'pragma inline' in 
> Ada...)

I don't know of any such pragma or property in Perl5. There are some
rules that will perl inline things automatically. The rules are that it
has to happen at compile time and that the to-be-inlined expression is
constant. Constant doesn't mean that it has to be a literal. It just has
to be evaluable at compile time. Also, you need an empty prototype '()'
on these functions.

Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 4823
***************************************


home help back first fref pref prev next nref lref last post