# November 2004 Archives

## Perl Debugger Quick Reference

Perl's debugger is powerful but somewhat esoteric. The core perldebtut tutorial is a good introduction, but who wants to skim through pages of documentation when you only need a quick refresher on the syntax of a command?

Let this printable (PDF) Perl Debugger Quick Reference card, excerpted from Richard Foley's Perl Debugger Pocket Reference, be your guide instead.

Editor's note: Unix users, we've had reports that Adobe Acrobat 5 has trouble opening this file. We're looking into this. In the meantime, xpdf and other tools appear to work correctly.

## This Week in Perl 6, November 9 - 15 2004

All~

Welcome to yet another Monday summary. This would have been a Sunday summary, but Avernum (from Spiderweb Software) forcibly prevented it. As usual, we will start out with Perl 6 Language.

### Perl 6 Language

#### Modules and Exports

Aaron Sherman wanted to know some specifics about exporting things from modules. In particular, he did not want to have to retype a whole bunch of things. Larry gave an answer indicating that some of what Aaron wants should occur, but some things are difficult for good reason.

#### AUTOCLASS(DEF)? Hooks

Rod Adams wanted to know if he could get AUTOCLASS and AUTOCLASSDEF hooks. Larry told him that he probably could. Rod also wanted module name aliasing. Larry told him that he could. Rod wanted to have module names with arbitrary strings. Larry told him that he could. Rod wanted to be able to load multiple versions of the same module. Larry told him that he could. The summarizer wanted each question of a different focus to be in a different message. Hopefully, Larry will tell him that they should...

#### Matching the nth Occurrences

Sudarshan Gaikaiwari wanted to know how to match the "second last" occurrence in Perl 6 rules. I think he might have posted directly to Google Groups, as I did not receive it in my email and nobody replied. The example Sudarshan gave matches the seconded occurrence. As I am not sure what Sudarshan meant by "2nd last", I will answer the question I do know. m:2nd/foo/ will match the second occurrence of foo. You can access the nth occurrence similarly.

### Perl 6 Compilers

Once again it is a race to see whether someone posts a comment to, or Google picks up, Perl 6 Compilers first.

### Parrot

Welcome to the week of the continuation. If continuations make your head hurt overly, I advise taking a few Advils before continuing. If continuations are the way you naturally think, I advise you to stop playing with LISP compilers.

#### String Pinning

Bernhard Schmalhofer wanted to pass the same C string into two different external functions so that the first could do things to it that the second required. However, the solution that he found kept eating his string after the first invocation. Dan and Leo concluded that using the b parameter for NCI is correct in this situation.

#### GC Invocation

Last week Leo posted a radical idea about GC invocation. I decided not to invoke Warnock's Dilemma too soon. This week, I invoke it.

#### perl vs. /usr/bin/perl

Gerd Pokorra requested that #! perl change to #! /usr/bin/perl. Although Warnock applied, I think this will likely not happen. Not all systems have Perl installed in /usr/bin/ and people might want to change which perl to invoke by changing their paths.

#### Command Line Support for Various Compilers

Will Coleda added a TODO item so that Parrot can take various compiler arguments on the command line. What are you waiting for?

#### Register Stomping

Matt Diephouse had troubles with his newly updated Forth compiler. The verdict seems to be that he has uncovered a bug. To quote Matt, "*sigh*."

#### Calling Continuations, Basic Blocks, and Register Allocation

Either Leo or Jeff Clites (I don't recall who) started what is probably the largest thread for this week, focusing on register allocation and continuation troubles. Apparently the presence of continuations can unduly extend the lifetime of registers (as can try-catch things, but they seem less important). The suggested solutions all have some shortcomings, although it appears that only using lexicals is winning.

#### Basic Compilation Example

Jeff Clites wondered how something like (a + b) would compile. The answer is to initialize an intermediate PMC to Undef, which will morph as appropriate.

#### Eval Changes

Leo updated the implementation of eval to make it even cooler, or possibly just clean it up and fix some bugs ... I forget.

#### Basic Operations for MMD

Dan asked for volunteers to spec out the basic vtable and MMD functions for CLS (common language specification-or-other). Sam Ruby said he would be willing to take a stab at it in a few weeks. One week has gone by and Sam grows ever closer to stabbing things.

#### No Limit on IMCC Identifier Length

Will Coleda noted that there was no limit on the length of IMCC identifiers. Here come the eval buffer overflow attacks....

#### Duplicate Local Labels Break PASM

Will noticed that duplicate local labels cause IMCC to output broken PASM. I could be mistaken, but I though that IMCC -> PASM has been broken for a while...

#### Parrot API

Leo wondered if the parrot_api.pl could be less strict about what it thinks is and is not public. Jarkko Hietaniemi responded that this was not his call to make, and silence reigned supreme.

#### Empty Sub Troubles

Will Colleda posted a bug for empty subs in IMCC. Stéphane Payrard provided a fix. Leo applied it.

#### Languages with Object Support?

Jeff Horwitz wondered if there were any languages with object support that he could bend to the evil ends of mod_parrot. While no one answered, I think Parakeet might be such a language....

#### WinXP Problems

Christian Lott has been having troubles with WinXP, in particular with ops2vim.pl. Read on for the blow-by-blow.

#### Strings + Working Correctly = Pain

In his noble efforts to make Parrot respect foreign languages and cultures, while not necessitating ICU, Dan has massively reworked strings. He reports ... progress. He also posed a question for all to ponder: "How global should the defaults be?"

#### runtime/parrot/library/config.pbc

Nicholas Clark wondered what would generate this file. Leo answered. Nicholas tracked his problem down to a quirk in FreeBSD make and fixed it.

#### #line Directives from PMC Files

Nicholas Clark announced his triumph over #line directives in pmc2c2.pl. People were impressed, but promptly asked how to turn it off. Kids these days don't appreciate what they have. ;-)

#### Tail Calls

Jeff Clites asked about tail calls in the presence of continuations. After much debate, the consensus seems to be that they don't affect each other much at all. In fact, continuations make tail calls easier. However, the topic was broached as to whether these were an optimization that IMCC should detect, or should compilers generate them explicitly. I think the final decision was compiler generated, although I doubt I would be alone in not minding if IMCC had a flag to allow it to add them as it saw fit....

#### Character Classes

Patrick R. Michaud wanted to know if Parrot had character class support (that is, checking membership). Leo responded that it would after Dan's aforementioned string stuff.

#### POSTCOMP vs. LOAD

Leo asked about the differences between POSTCOMP and LOAD. Dan provided the answer: POSTCOMP runs only when (and as soon as) the sub is compiled. LOAD runs when the sub is loaded. This need not be the same time if the source is used to generate bytecode that is later executed.

#### Register Allocation/Spilling/Volatility

Jeff Clites suggested using variable-size register frames with explicit, volatile and non-volatile sections. Leo responded that this would cause serious code bloat, and pointed him to his and Miroslav Silovic's "watermark" scheme. Others voiced support for this as well as removing the implicit operands. Dan said no.

#### AIX JIT Gnomes

Adam Thomason observed that the AIX JIT problems have gone away and thanked the gnomes responsible. Remember, the proper sacrifice for little people like gnomes are mini-Milanos or other reduced-size cookies (nothing from Keebler as the gnomes and elves have long-unresolved issues).

#### Register Allocation (Again)

Bill Coffman's register allocator (or should I say his implementation of the Matula/Chaitin/Briggs algorithm) grows ever closer to being committed (although my initial prediction of two weeks ago was clearly wrong). In fact, his algorithm is so good that it even turned up bugs from other pieces of the code. Dan started a test run on his evil code, so we should have truly stressed performance numbers within the next several fortnights.

#### IMCC Segfault on Bad if

Gopal V found a way to make IMCC segfault. I think it is still waiting for a fix....

#### No perldoc == BIG FAT WARNING

James deBoer submitted a patch to fail if the configuration step did not find perldoc last week. This week the request has gone out to modify it to warn in a big and preferably fat way. No answer yet.

#### RT Clean Up

Will Coleda, whose diligent minding of the RT queue is much appreciated, closed a few tickets that no longer apply.

#### BASIC Compiler

Will "Dr. Frankenstein" Coleda has attempted to resurrect the basic compiler with some major surgery. He is making progress. Joshua Gatcomb put out a request for a new maintainer.

Luke Palmer provided a patch for making Configure.pl slightly more informative. Brent "Dax" Royal-Gordon applied it.

#### Find-Method Inheritance

Sam Ruby asked for comment before committing a patch to allow calling of attributes as methods and to allow inheritance of attributes. When no one commented, he committed.

Gabe Schaffer pointed out some issues with threads and events from a Win32 perspective. Leo pointed out that this has not yet been fully implemented/abstracted/documented and observed that Gabe would be a welcome volunteer.

#### Core Dump on japh16

Bernhard Schmalhofer noticed that japh16 core dumps. He also submitted a simplistic fix.

### The Usual Footer

If you find these summaries useful or enjoyable, please consider contributing to the Perl Foundation to help support the development of Perl. You might also like to

## Cross-Language Remoting with mod_perlservice

### Mod_perlservice? What is That?

Mod_perlservice is a cool, new way to do remoting -- sharing data between server and client processes -- with Perl and Apache. Let's start by breaking that crazy name apart: mod + perl + service.

Mod means that it's a module for the popular and ubiquitous Apache HTTP Server. Perl represents the popular and ubiquitous programming language. Service is the unique part. It's the new ingredient that unifies Apache, Perl, and XML into an easy-to-use web services system.

With mod_perlservice, you can write Perl subs and packages on your server and call them over the internet from client code. Clients can pass scalars, arrays, and hashes to the server-side subroutines and obtain the return value (scalar, array, or hash) back from the remote code. Some folks refer to this functionality as "remoting" or "RPC," so if you like you can say mod_perlservice is remoting with Perl and Apache. You can write client programs in a variety of languages; libraries for C, Perl, and Flash Action Script are all ready to go.

Now that you know what mod_perlservice is, let's look at why it is. I believe that mod_perlservice has a very clean, easy-to-use interface when compared with other RPC systems. Also, because it builds on the Apache platform it benefits from Apache's ubiquity, security, and status as a standard. Mod_perlservice sports an embedded Perl interpreter to offer high performance for demanding applications.

### How Can I Use mod_perlservice?

Mod_perlservice helps create networked applications that require client-server communication, information processing, and sharing. Mod_perlservice is for applications, not for creating dynamic content for your HTML pages. However, you surely can use it for Flash remoting with Perl. Here are some usage examples:

• A desktop application (written using your favorite C++ GUI library) that records the current local air temperature and sends it to an online database every 10 minutes. Any client can query the server to obtain the current and historical local air temperature of any other participating client.
• A Flash-based stock portfolio management system. You can create model stock portfolios and retrieve real-time stock quote information and news.
• A command-line utility in Perl that accepts English sentences on standard input and outputs the sentences in French. Translation occurs in server-side Perl code. If the sentence is idiomatic and the translation is incorrect, the user has the option of sending the server a correct translation to store in an online idiom database.

### How Do I Start?

Let's move on to the fun stuff and set up a working installation. Before we begin, make sure you have everything you need! You need Apache HTTPD, Perl, Expat, mod_perlservice, and a mod_perlservice client library (Perl Client | C Client | Flash Client). You must download a client library separately, as the distribution does not include any clients! In your build directory:

myhost$tar -xvzf mod_perlservice.tar.gz myhost$ cd mod_perlservice
myhost$./configure myhost$ make
myhost$make install If everything goes to plan, you'll end up with a fresh mod_perlservice.so in your Apache modules directory, (usually /etc/apache/modules). Now it's time to configure Apache to use mod_perlservice. cd into your Apache configuration directory (usually /etc/apache/conf) Add the following lines to the file apache.conf (or httpd.conf, if you have only a single configuration file): LoadModule perlservice_module modules/mod_perlservice.so AddModule mod_perlservice.c Add the following lines to commonapache.conf, if you have it and httpd.conf if you don't: <IfModule mod_perlservice.c> <Location /perlservice> SetHandler mod_perlservice Allow From All PerlApp myappname /my/app/dir #Examples PerlApp stockmarket /home/services/stockmarket PerlApp temperature /home/services/temperature </Location> </IfModule> Pay close attention to the PerlApp directive. For every mod_perlservice application you want to run, you need a PerlApp directive. If I were creating a stock market application, I might create a directory: /home/services/stockmarket and add the following PerlApp directive: PerlApp stockmarket /home/services/stockmarket This tells mod_perlservice to host an application called stockmarket with the Perl code files located in the /home/services/stockmarket directory. You may run as many service applications as you wish and you may organize them however you wish. With the configuration files updated, the next step is to restart Apache: myhost$ /etc/init.d/apache restart
or
myhost$apachectl restart Now if everything went as planned, mod_perlservice should be installed. Congratulations! ### An Example Let's create that stock portfolio example mentioned earlier. It won't support real-time quotes, but will instead create a static database of common stock names and historical prices. The application will support stock information for General Electric (GE), Red Hat (RHAT), Coca-Cola (KO), and Caterpillar (CAT). The application will be stockmarket and will keep all of the Perl files in the stock market application directory (/home/services/stockmarket). The first file will be quotes.pm, reading as follows: our$lookups = {
"General Electric" => "GE",
"Red Hat"          => "RHAT",
"Coca Cola"        => "KO",
"Caterpillar Inc"  => "CAT"
};
our $stocksymbols = { "GE" => { "Price" => 33.91, "EarningsPerShare" => 1.544 }, "RHAT" => { "Price" => 14.96, "EarningsPerShare" => 0.129 }, "KO" => { "Price" => 42.84, "EarningsPerShare" => 1.984 }, "CAT" => { "Price" => 75.74, "EarningsPerShare" => 4.306 } }; package quotes; sub lookupSymbol { my$companyname = shift;
return $lookups->{$company_name};
}

sub getLookupTable {
return $lookups; } sub getStockPrice { my$stocksymbol = shift;
return $stocksymbols->{$stocksymbol}->{"Price"};
}
sub getAllStockInfo {
my $stocksymbol = shift; return$stocksymbols{$stocksymbol}; } 1; That's the example of the server-side program. Basically, two static "databases" ($lookups and $stocksymbols) provide information about a limited universe of stocks. The above methods query the static databases; the behavior should be fairly self-explanatory. You may have as many .pm files in your application as you wish and you may also define as many packages within a .pm file as you wish. An extension to this application might be a file called news.pm that enables you to fetch current and historical news about your favorite stocks. Now let's talk some security. As it stands, this code won't work; mod_perlservice will restrict access to any file and method you don't explicitly export for public use. Use the .serviceaccess file to export things. Create this file in each application directory you declare with mod_perlservice or you'll have no access. An example file might read: <ServiceAccess> <AllowFile name="quotes.pm"> Allow quotes::* </AllowFile> </ServiceAccess> In the stock market example, this file should be /home/services/stockmarket/.serviceaccess. Be sure that the apache user does not own this file; that could be bad for security. This file allows access to the file quotes.pm and allows public access to all (*) the methods in package quotes. If I want to restrict access only to getStockPrice, I would have written Allow quotes::getStockPrice. After that, I could add access to lookupSymbol with Allow quotes::lookupSymbol. To make quotes.pm public carte blanche, use Allow *. You won't need to restart Apache when you make changes to this file as it reloads automatically. ### Client Code Well, so far I've only shown you half the story. It's time to create some client-side code. This client example uses the Flash "PerlService" library, just one of the client-side interfaces to mod_perlservice. The Flash client works well for browser interfaces while the Perl and C clients can create command-line or GUI (ie, GTK or Qt) applications. This article is on the web, so we'll give the Flash interface a spin and then go through an example in Perl. The first code smidgen should go in the first root frame of your Flash application. It instantiates the global PerlService object and creates event handlers for when remote method calls return from the server. The event handlers output the requested stock information to the display box. #include "PerlService-0.0.2.as" // Create a global PerlService object // Tell the PerlService object about the remote code we want to use: // arg1) host: www.ivorycity.com // arg2) application: stockmarket // arg3) file: quotes.pm // arg4) package: quotes _global.ps = new PerlService("www.ivorycity.com","stockmarket","quotes.pm","quotes"); // First declare three callback functions to handle return values function onStockPrice(val) { output.text = "StockPrice: " + symbolInput.text + " " + val + "\n" + output.text; } function onAllStockInfo(val) { output.text = "Stock Info: " + allInfoInput.text + "\n" + "\tPrice: " + val.Price + "\n" + "\tEarnings Per Share: " + val.EarningsPerShare + "\n" + output.text; } function onLookupSymbol(val) { output.text = "Lookup Result: " + symbolInput.text + " " + val + "\n" + output.text; } // Register callback handlers for managing return values from remote methods // ie, onStockPrice receives the return value from remote method getStockPrice ps.registerReplyHandler( "getStockPrice", onStockPrice ); ps.registerReplyHandler( "getAllStockInfo", onAllStockInfo ); ps.registerReplyHandler( "lookupSymbol", onLookupSymbol ); Now for the code that makes things happen. The following code attaches to three separate buttons. When clicked, the buttons call the remote Perl methods using the global PerlService object. Flash Action Script is an event-driven system, so click event-handlers will call the remote code and return event-handlers will do something with those values. Figure 1. Button and code associations. When a user presses Button 1, call the remote method getStockPrice and pass the text in the first input box as an argument. on (release) { ps.getStockPrice(box1.text); } When the user presses Button 2, call the remote method getAllStockInfo and pass the text in the second input box as an argument. on (release) { ps.getAllStockInfo(box2.text); } When the user presses Button 3, call the remote method lookupSymbol and pass the text in the third input box as an argument. on (release) { ps.lookupSymbol(box3.text); } That's the entire Flash example. Here is the finished product. #### Perl Client Not everyone uses Flash, especially in the Free Software community. The great thing about mod_perlservice is that everyone can join the party. Here's a Perl Client that uses the same server-side stock market API.  use PService; my$hostname = "www.ivorycity.com";
my $appname = "stockmarket"; my$filename = "quotes.pm";
my $package = "quotes"; #Create the client object with following arguments: #1) The host you want to use #2) The application on the host #3) The perl module file name #4) The package you want to use my$ps = PSClient->new( $hostname,$appname, $filename,$package );

# Just call those remote methods and get the return value
my $price =$ps->getStockPrice("GE");
my $info =$ps->getAllStockInfo("RHAT");
my $lookup =$ps->lookupSymbol("Coca Cola");

#Share your exciting new information with standard output
print "GE Price: " . $price . "\n"; print "Red Hat Price: " .$info->{Price} . "\n";
print "Red Hat EPS: " . $info->{EarningsPerShare} . "\n"; print "Coca-Cola's ticker symbol is " .$lookup . "\n";

Using the PSClient object to call remote methods might feel a little awkward if you expect to call them via quotes::getStockPrice(), but think of the $ps instance as a proxy class to your remote methods, if you like. If things don't work, use print$ps->get_errmsg(); to print an error message. $ps->get_errmsg(); That's a local reserved function, so it doesn't call the server. It's one of a few reserved functions detailed in the Perl client reference. As you can see, it requires much less work to create an example with the Perl client. You simply instantiate the PSClient object, call the remote methods, and do something with the return values. That's it. There is no protocol decoding, dealing with HTTP, CGI arguments, or any of the old annoyances. Your remote code may as well be local code. ### Thanks for Taking the Tour That's mod_perlservice. I'm sure many of you who are developing client-server applications can see the advantages of this system. Personally, I've always found the existing technologies to be inflexible and/or too cumbersome. The mod_perlservice system offers a clean, simple, and scalable interface that unites client-side and server-side code in the most sensible way yet. What's next? mod_parrotservice! ## TEST ## This is a test Again... ## This Week in Perl 6, November 2 - 8 2004 Welcome to yet another summary, brought to you (once again) with the aid of the musical stylings of Dar Williams and Soul Coughing and a small, stuffed elephant name Aliya. And, without further ado, I give you Perl 6 Language (whose traffic has picked up a little). ### Perl 6 Language #### What Was that Anonymous Thing? Juerd wondered what things could be named and what could be anonymous. Larry provided the answer: Subtypes, Enums, Lists (Lazy and Eager), Grammars, and Packages, but then threatened to attack Juerd with hot grits. #### Updated Apocalypses and Synopses Larry proved links to the current versions of the various Apocalypses and Synopses. Unfortunately he forgot to start a new thread with his message.... #### Suggested Warning for Overriding Operators Aaron Sherman wanted to receive a warning for defining things like multi sub *infix:+(...) {...}. But Larry reasoned that anyone who'd use the * there does not care for warnings. ### Perl 6 Compiler Last week, I bemoaned my lack of Google (and thus links). But a couple kind souls pointed out that I could get links straight from the horses mouth at nntp.perl.org. All I can say is, ::shrug:: "Who knew that there was an Internet outside of Google?" Fortunately, I do not have to admit to its existence as there were no messages this week. ### Parrot Internals #### She-bangs for None!! Last week James deBoer offered a patch to remove all of the shebang lines from config/*.pl (after his initial patch to add them to all of them was turned away). Warnock applies. #### Solaris 9 Troubles Christian Aperghis-Tramoni has some trouble while trying to install on Solaris 9. Warnock applies. #### More Vtables Leo wanted to add a finalize vtable entry (in addition to destroy, which is apparently used for free memory and not active resources). Jeff commented on the difficulties implicit in finalizing stuff, and the thread ran out of gas. #### Build Dynclasses by Default Last week, Leo was stalling to hear about success and failures before adding them to the default build. Brent "Dax" Royal-Gordon and Sam Ruby both chimed in with success. And so they did. #### Register Frame Recycling Leo added in some basic continuation recycling. Dan didn't like that it required the user to clone return continuations into full ones. Leo agreed, but felt that a returncc function would be needed first. I wondered why we needed this recycling and couldn't just let the DOD/GC do it for us. The answer: speed. #### Upcase Binary Strings Dan wondered what should happen if you tried to play with the case of a binary encoded string. The consensus seems to be either throw an exception or nothing, depending on settings. #### Setref Poorly Named Sam Ruby was initially confused by the strange behavior of setref. Leo told him that it was intended to set a reference inside a reference type and noted that classes needs a clean up. With the advent of dynclasses, this sounds like a job for some adventurous lurker... #### Tracebacks PMC v. Ops Leo wondered if we should have a PMC that could access the entire call chain and do whatever evil it wanted. Dan conjectured that this sort of thing was evil enough that ops might be well advised. Leo initially put some methods into the continuation to do this, but later thought about putting them into the interpreter instead. I like the interp idea. #### Parrot -t Memory Leaks Last week our fearless leader notice some significant memory leaks with parrot -t. This week our fearless pumpking fixed them. #### Performance Graphs Matt Diephouse (assisted by Joshua Gatcomb) provided a pointer to a page of periodic Parrot performances, provided as pretty pictures. Please provide possible improvement pointers. #### Uniline yield() and return() Stéphane Payrard (whose name Google objects to strenuously) re-sent his patch for uniline yield and return in PIR. Leo applied the patch. #### Mod_parrot 0.1 Jeff Horwitz released mod_parrot 0.1. Pretty nifty. download mod_parrot #### IO Auto-Flush Troubles Christian Aperghis-Tramoni wondered how to make stdout not buffer away his prompt. The answer (provided by Mary Pauley and Luke Palmer) requires using pioctl and strange magic numbers. #### BigChanges--; release++? Since the big indirect register change has gone through, some voices suggested putting out a 0.1.2 release. Leo felt that it was too soon, but seemed to be holding a minority opinion. I vote that we release after the new register allocator (and possibly Dan's string stuff depending on how long it takes). #### Dan's String Stuff Dan is about to make some "Irrevocable Changes" so he decided to do his work in a branch named pluggable_encodings, assuming he can use CVS (which is surprisingly hard at times). Because no one screamed foul, I think it is a safe assumption. #### Clone mmd Sam Ruby submitted a patch adding mmd_clone for dynclasses. Leo suggested an alternate approach, and Warnock['s Dilemma] took over. #### True Coroutines Klaas-Jan Stol wondered if Parrot had "true" coroutine because Roberto Ierusalimschy (of Lua fame) called it into question. Some confusion ensued as to what the platonic ideal of a coroutine actually is, but the answer seems to be: we should and if they aren't, patches welcome. #### Trouble with Closures and Subs Klaas-Jan Stol was having trouble with closures and subs. Many people provided some very useful pointers. If you are writing a compiler for Parrot you should read this thread carefully. If you are writing a summary for Parrot you should skim it and punt. #### Shared Library and Dynclasses Sam Ruby wondered if dynclasses should link to libparrot.so. Dan provided the answer: yes. Sam Ruby went on to suggest that if most PMCs would eventually become dynclasses, then (to reduce executable size, the Parrot executable should probably also link to libparrot.so rather than including all of it. No one commented on this observation. #### Search Paths and Libraries Dan wants to stop being annoyed by library path issues. He figures that the right way to do this is to allow dynamic library loading. Best of all he wants the code to do that be in the library. Thus he put out a request for the ability to embed bytecode into an executable. Brent "Dax" Royal-Gordon provided a slightly too-evil method of doing this. Other slightly less-evil (or even good) options would definitely be received thankfully. #### Benchmarks? Tests? Or Both? Joshua Gatcomb noticed that some benchmarks fail on occassion. Matt Diephouse suggested making them tests too. Leo felt that would be fine provided they did not take too long to run. #### Fibonacci Still Slow It is odd how the wheel comes full circle. Originally designed as an exercise in addition for students, the Fibonacci Sequence has some really interesting mathematical properties. While completely ignoring its unexpected niftiness (and explicit formula), this miraculous sequence is still used as busy work for poor creatures. This time the creature is Parrot, and despite Leo's best efforts, it is still slow. There was some talk of how to optimize this before Dan put the smack down all of it: "No more performance changes. Period. We get Parrot fully functional first." #### Parrot on Windows Jerry Wiltz wondered how to get Parrot on his poor Win XP box. Fred and Georgy provided many pointers. Christian Lott also had trouble, but Nicholas Clark, Ron Blaschke, Peter Sinnott, and Steve Peters all provided pointers. #### Parrot Build Issues Jack J. Woehr was having trouble building parrot on his Sun. Leo provided the needed help. Then ICU became problematic. Many people provided help and he eventually got it running Forth, which promptly segfaulted. Jack sounded discouraged, but he really should stay with it now that he has overcome the hard part.... #### Detecting perldoc James deBoer wondered if we should detect the presence of perldoc and fail to configure if it is missing. The consensus seems to be that we should detect the absence of perldoc, but if it is not there throw up a big fat warning and proceed. #### Pow and Other Ops There was/is a fairly long and ongoing discussion about ops on PMCs, which Sam Ruby unwittingly started when he asked for MMD pow. While there are people on all sides, it appears likely that the ops will stay. #### C on Parrot? Bloves wondered what the current state of C on Parrot was. But I think he posted it through Google Groups (which does not actually reach the list) as I did not find it in my email. The answer is it essentially non-existent, but if you are feeling brave/insane/suicidal patches welcome. #### Streams and Filters Ron Blaschke tracked does the problem with t/library/streams.t #14 on Win32. The guilty party is line endings. One workaround would be to set the file in question to binary in CVS (although that feels like cheating). #### AIX PPC JIT Adam Thomason provided a patch to fix some warnings. Leo applied it. #### Register Allocation/Volatility Despite Dan's line-in-the-sand strong statements about no more optimization, Jeff Clites and Leo tossed about some radical ideas for how to speed everything up. #### GC Invocation Leo suggested changing the GC from one that interrupts everybody and does its thing, to one that waits its turn and does its thing. I am concerned that this could lead to resource starvation in a multithreaded system, but nobody else posted anything. Of course, he only suggested this today. #### Eval Questions Leo wants some answers to some eval questions before he tries to clean up dynamic code compiling. Answers?? #### Include Perl 6 Files in Config Gerd Pokorra wants to be able to run Perl 6 from anywhere. He even provided a means of achieving this end (although not in unified diff format as is the custom). #### pioctl -> segfault Stéphane Payrard received a segfault while playing with the previously mentioned pioctl magic numbers. Leo speculates that this might be due to the lack of an end opcode. #### [TODO] Improve parrot-config.imc Takers wanted. #### Missing Arguments Klaas-Jan Stol wondered how to detect missing arguments. Leo and Dan both pointed to the argument count registers. #### Update to embed.pod Stéphane Payrard provided an update to embed.pod. Leo applied it, but Brent "Dax" Royal-Gordon cried foul over the including of parrot.h. Dan agreed with Brent, and Stéphane provided a patch to remove the offending line. #### Calling Conventions, Tracebacks, and Register Allocations Leo suggested a new way to invoke functions that would clean up calling, tracebacks, and register allocation. While such a change would have great aesthetic value, Dan declared it premature as Parrot is not yet fully specified. Doubtless this will re-arise later, as aesthetics is a powerful motivator. ### The Usual Footer If you find these summaries useful or enjoyable, please consider contributing to the Perl Foundation to help support the development of Perl. You might also like to send feedback. ## Implementing Flood Control Accordingly to Merriam-Webster Online, "flood" means: 1: a rising and overflowing of a body of water especially onto normally dry land; 2: an overwhelming quantity or volume. In computer software there are very similar situations when an unpredictable and irregular flow of events can reach higher levels. Such situations usually are not comfortable for users, either slowing down systems or having other undesired effects. Floods can occur from accessing web pages, requesting information from various sources (ftp lists, irc services, etc.), receiving SMS notification messages, and email processing. It is obvious that it is not possible to list all flood cases. "Flood control" is a method of controlling the processing-rate of a stream of events. It can reject or postpone events until there are available resources (CPU, time, space, etc.) for them. Essentially the flood control restricts the number of events processed in a specific period of time. ### Closing the Gates To maintain flood control, you must calculate the flood ratio, which is: Figure 1. Flood ratio equation. fr flood ratio ec event count tp time period for ec To determine if a flood is occurring, compare the flood ratio to the fixed maximum (threshold) ratio. If the result is less than the threshold, there's no flood. Accept the event. If the result is higher, refuse or postpone the event. Figure 2. Comparing the ratios. ec event count tp time period for ec fc fixed event count (max) fp fixed time period for fc It is possible to keep an array of timestamps of all events. Upon receipt of a new event, calculate the time period since the oldest event to use as the current count/time ratio. This approach has two drawbacks. The first is that it uses more and more memory to hold all of the timestamps. Suppose that you want only two events to happen inside a one-minute period, giving two events per minute. Someone can trigger a single event, wait half an hour, and finally flood you with another 58 requests. At this point the ratio will be 1.9/min., well below the 2/min. limit. This is the second drawback. A better approach is to keep a sliding window either of events (fc) or time period (fp). This period window requires an array of the last events. This array size is unknown. (The specific time units are not important, but the following examples use minutes.)  past now Timeline: 1----2----3----4----5----6----7----8----9---> (min) Events: e1 e2 e3 e4 e5 e6 e7 This timeline measures event timestamps. To calculate the flood ratio, you count events newer than the current time window of size fp. And check against a ratio of four events in three minutes: Time now: 9 Time window: from 9-3 = 6 to now(9), so window is 6-9 Oldest event: e5 (not before 6) Event count: 3 (in 6-9 period) Flood ratio: 3/3 This ratio of 3/3 is below the flood threshold of 4/3, so at this moment there is no flood. Perform this check at the last event to check. In this example, this event is e7. After each check, you can safely remove all events older than the time window to reduce memory consumption. The other solution requires a fixed array of events with size fc. With our 4ev/3min example, then:  past now Timeline: <--5----6----7----8----9---> (min) Events: e4 e5 e6 e7 The event array (window) is size 4. To check for a flood at e7, we use this: Window size "fc": 4 First event time: e4 -> 5 Last event time: e7 -> 9 Time period "tp": 9-5 = 4 Flood ratio is: 4/4 The ratio of 4/4 is also below the threshold of 4/3, so it's OK to accept event e7. When you must check a new event, add it to the end of the event array (window) and remove the oldest one. If the new event would cause a flood, remember to reverse these operations. If the flood check fails, you can find a point in the future when this check will be OK. This makes it possible to return some feedback information to the user indicating how much time to wait before the system will accept the next event: Figure 3. Time until next event equation. ec event count (requests received, here equal to fc) fc fixed event count (max) fp fixed time period for fc now the future time point we search for ot oldest event time point in the array (event timestamp) Figure 4. Simplified time until next event equation. Figure 5. The time-to-wait equation. time the actual current time (time of the new event) wait time period to wait before next allowed event If wait is positive, then this event should be either rejected or postponed. When wait is 0 or negative, it's OK to process the event immediately. ### The Code In the following implementation I'll use a slightly modified version of the sliding window of events. To avoid removing the last event and eventually replacing it after a failed check, I decided to check the current flood ratio with the existing events array and with the time of the new one:  past now Timeline: <--5----6----7----8----9---> (min) Events: e3 e4 e5 e6 (e7) Window size fc: 4 (without e7) First event time: e4 -> 5 Last event time: e7 -> 9 Time period tp: 9-5 = 4 Flood ratio is: 4/4 This seems a bit strange at first, but it works exactly as needed. The check is performed as if e6 is timed as e7, which is the worst case (the biggest time period for the fixed event window size). If the check passes, than after removing e3, the flood ratio will be always below the threshold! Following this description I wrote a function to call for each request or event that needs flood control. It receives a fixed, maximum count of requests (the events window size) and a fixed time period. It returns how much time must elapse until the next allowed event, or 0 if it's OK to process the event immediately. This function should be generic, so it needs some kind of event names. To achieve this there is a third argument -- the specific event name for each flood check. Here is the actual code: # this package hash holds flood arrays for each event name # hash with flood keys, this is the internal flood check data storage our %FLOOD; sub flood_check { my$fc = shift; # max flood events count
my $fp = shift; # max flood time period for$fc events
my $en = shift; # event name (key) which identifies flood check data$FLOOD{ $en } ||= []; # make empty flood array for this event name my$ar = $FLOOD{$en }; # get array ref for event's flood array
my $ec = @$ar;          # events count in the flood array

if( $ec >=$fc )
{
# flood array has enough events to do real flood check
my $ot =$$ar[0]; # oldest event timestamp in the flood array my$tp = time() - $ot; # time period between current and oldest event # now calculate time in seconds until next allowed event my$wait = int( ( $ot + ($ec * $fp /$fc ) ) - time() );
if( $wait > 0 ) { # positive number of seconds means flood in progress # event should be rejected or postponed return$wait;
}
# negative or 0 seconds means that event should be accepted
# oldest event is removed from the flood array
shift @$ar; } # flood array is not full or oldest event is already removed # so current event has to be added push @$ar, time();
# event is ok
return 0;
}

I've put this on the CPAN as Algorithm::FloodControl.

To test it, I wrote a simple program that accepts text, line by line, from standard input and prints each accepted line or the amount of time before the program will accept the next line.

#!/usr/bin/perl
use strict;
use Algorithm::FloodControl;

while(<>)
{
# time is used to illustrate the results
my $tm = scalar localtime; # exit on quit' or exit' strings exit if /exit|quit/i; # FLOOD CHECK: allow no more than 2 same lines in 10 seconds # here I use the actual data for flood event name! my$lw = flood_check( 2, 10, $_ ); if($lw ) # local wait time
{
chomp;
print "WARNING: next event allowed in $lw seconds (LOCAL CHECK for '$_')\n";
next;
}
print "$tm: LOCAL OK:$_";

# FLOOD CHECK: allow no more than 5 lines in 60 seconds
my $gw = flood_check( 5, 60, 'GLOBAL' ); if($gw ) # global wait time
{
print "WARNING: next event allowed in $gw seconds (GLOBAL CHECK)\n"; next; } print "$tm: GLOBAL OK: $_"; } I named this floodtest.pl. The of the test were: (">" marks my input lines) cade@aenea:~$ ./floodtest.pl
> hello
Wed Feb 17 08:25:35 2004: LOCAL  OK: hello
Wed Feb 17 08:25:35 2004: GLOBAL OK: hello
> hello
Wed Feb 17 08:25:38 2004: LOCAL  OK: hello
Wed Feb 17 08:25:38 2004: GLOBAL OK: hello
> hello
WARNING: next event allowed in 5 seconds (LOCAL CHECK for 'hello')
> bye
Wed Feb 17 08:25:43 2004: LOCAL  OK: bye
Wed Feb 17 08:25:43 2004: GLOBAL OK: bye
> hello
Wed Feb 17 08:25:45 2004: LOCAL  OK: hello
Wed Feb 17 08:25:45 2004: GLOBAL OK: hello
> see you
Wed Feb 17 08:25:48 2004: LOCAL  OK: see you
Wed Feb 17 08:25:48 2004: GLOBAL OK: see you
> next time
Wed Feb 17 08:25:52 2004: LOCAL  OK: next time
WARNING: next event allowed in 43 seconds (GLOBAL CHECK)
> one more try?
Wed Feb 17 08:26:09 2004: LOCAL  OK: one more try?
WARNING: next event allowed in 26 seconds (GLOBAL CHECK)
> free again
Wed Feb 17 08:26:31 2004: LOCAL  OK: free again
WARNING: next event allowed in 4 seconds (GLOBAL CHECK)
> free again
Wed Feb 17 08:26:42 2004: LOCAL  OK: free again
Wed Feb 17 08:26:42 2004: GLOBAL OK: free again

You can see that I could not enter "hello" 3 times during the first 10 seconds but still I managed to enter one more "hello" a bit later (the 10-second flood had ended for the "hello" line) and 2 other lines before the global flood check triggered (5 lines for 1 minute). After 60 seconds, floodtest.pl finally accepted my sixth line, "free again."

The next sections show how to use flood control in several applications. These examples are not exhaustive but are very common, so they will work as templates for other cases.

Imagine an IRC bot (robot) which can report scores from the local game servers. Generally this bot receives requests from someone inside IRC channel (a chat room, for those of you who haven�t used IRC) and reports current scores back to the channel. If this eventually becomes very popular, people will start requesting scores more frequently than it is useful just for fun, so there's a clear need for flood control.

I'd prefer to allow any user to request scores no more than twice per minute, but at the same time I want to allow 10 requests total every two minutes:

sub scores_request
{
my $irc = shift; # the IRC connection which I communicate over # this is a Net::IRC::Connection object my$channel = shift; # the channel where "scores" are requested
my $user = shift; # the user who requested scores # next line means: do flood check for$user and if it is ok, then
#                  check for global flood. this is usual Perl idiom.
my $wait = flood_check( 2, 60,$user ) || flood_check( 10, 120, '*' );
if( $wait ) # can be 0 or positive number so this check is simple { # oops flood detected, report this personally to the user$irc->notice( $user, "please wait$wait seconds" );
}
else
{
# it is ok, there is no flood, print scores back to the channel
$irc->privmsg($channel, get_scores() );
}
}

This code uses the Net::IRC module, so if you want to know the details of the notice() and privmsg() functions, check the module documentation.

This is good example of combining events, but it works correctly only if the second flood ratio (in this case 10/120) is greater than first one (2/60). Otherwise you should extend the flood_check() function with an array of events to check in one loop, so if any of them fails the internal storage will update. Perhaps Algorithm::FloodControl will have such a feature in the future.

Another common case is to limit the execution of resource-consuming web scripts (CGI).

### (Don't) Flood the Page!

If you want to limit CGI-script execution you will hit a problem: you must save and restore the flood-control internal data between script invocations. For this reason the Algorithm::FloodControl module exports another function called flood_storage, which can get or set the internal data.

In this example I'll use two other modules, Storable and LockFile::Simple. I use the first to save and restore the flood-control data to and from disk files and the second to lock this file to avoid corruptions if two or more instances of the script run at the same time:

#!/usr/bin/perl
use strict;
use Storable qw( store retrieve );
use LockFile::Simple qw( lock unlock );
use Algorithm::FloodControl;

# this is the file that should keep the flood data though /tmp is not
# the perfect place for it
my $flood_file = "/tmp/flood-cgi.dat"; # this is required so the web browser will know what is expected print "Content-type: text/plain\n\n"; # I wanted to limit the script executions per remote IP so I have to # read it from the web server environment my$remote_ip = $ENV{'REMOTE_ADDR'}; # first of all--lock the flood file lock($flood_file );

# now read the flood data if flood file exists
my $FLOOD = retrieve($flood_file ) if -r $flood_file; # load flood data into the internal storage flood_storage($FLOOD ) if $FLOOD; # do the actual flood check: max 5 times per minute for each IP # this is the place where more checks can be done my$wait = flood_check( 5, 60, "TEST_CGI:$remote_ip" ); # save hte internal data back to the disk store( flood_storage(),$flood_file );

# and finally unlock the file
unlock( $flood_file ); if($wait )
{
# report flood situation
print "You have to wait $wait seconds before requesting this page again.\n"; exit; } # there is no flood, continue with the real work here print "Hello, this is main script here, local time is:\n"; print scalar localtime; print "\n...\n"; There are various issues to consider, such as the save/restore method, time required, and locking, but in any case the scheme will be similar. ### Beep, Beep, Beep ... In this last example I'll describe a small program, a variation of which I use for (email) SMS notifications. I wanted to avoid scanning large mail directories so I made my email filter copy incoming messages into a separate folder. The program scans this copy folder every 10 minutes for new messages. If there are any, it sends a notification for each one to my mobile phone and removes the copy of the message. #!/usr/bin/perl use strict; use Algorithm::FloodControl; our$MAIL_ROOT = '/home/cade/mail';
our @SCAN = (
{ # this is my personal mail, I'd like to be notified often
FOLDER  => 'Personal2', # directory (mail folder) to scan
FC      => 20,          # fixed event count
FP      => 60*60,       # fixed time period, 1 hour
},
{ # this is a mailing list, I don't need frequent notifications
FOLDER  => 'AList2',    # directory (mail folder) to scan
FC      => 3,           # fixed event count
FP      => 20*60,       # fixed time period, 20 minutes
}
);
while(4)
{
process_folder( $_ ) for @SCAN; sleep(10*60); # sleep 10 minutes } sub process_folder { my$hr     = shift; # this is hash reference
my $fc =$hr->{ 'FC' };
my $fp =$hr->{ 'FP' };
my $folder =$hr->{ 'FOLDER' };

my @msg = glob "$MAIL_ROOT/$folder/*";
return unless @msg; # no messages found
for( @msg )
{
# there are new messages, so flood check is required
my  $wait = flood_check($fc, $fp,$folder );
if( $wait ) { # skip this pass if non-zero wait time is received for this folder print "FLOOD!$wait seconds required.\n";
return;
}
send_sms( $folder,$_ );
}
}

sub send_sms
{
my $folder = shift; my$file   = shift;
# implementation of this function is beyond the scope of this example
# so I'll point just that it extracts subject line from the message file
# and sends (over local sms gateway) text including folder name, time
# and subject

### Toolbox Setup Instructions

To setup PerlTidy:

1. Make sure you have Perl and PerlTidy installed. For Windows, grab the ActivePerl distribution from ActiveState and then download and install the PerlTidy script from SourceForge.
2. In your toolbox tab, click the Add Item button at the top; then select New Command.
3. The cursor starts off in the Command line, which you can specify as:

perl c:\path\to\perltidy -b [perltidy style prefs] %f

(-b specifies to tidy the file in place, making a .bak backup file.)

4. In the advanced section, put %D in the Start field to launch PerlTidy in the script's working directory.
5. Rename the Command to PerlTidy in the field at the top.
6. At this point, you can also go to the Key Binding tab and assign a key combination to run the command.
7. Save, open a Perl file and give it a shot, either using the key combination you assigned or by double clicking on the command from your Toolbox.

To setup a snippet, such as the HTML::Template tag:

1. In your toolbox tab, click the Add Item button at the top, and then select New Snippet.
2. Type in the text to insert when you run the snippet. In my case, I used:

<!-- TMPL_VAR NAME="" ESCAPE=HTML -->
3. Be sure to place the cursor between the quote marks and select the Maintain selected text or cursor position after insertion checkbox.
4. Name the snippet (I used tmplvar) at the top. You can also go to the Key Binding tab at the top and assign a key combination to run the snippet.
5. Save and then give it a shot, either using the key combination you assigned or by double clicking on the command from your Toolbox.
Visit the home of the Perl programming language: Perl.org