Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
blackoutdonnie
Jan 7, 2004

cooking with gas

floWenoL posted:

I disagree. His way reduces the time in which the variable is in an "invalid state", which arguably makes it clearer.

This. It's a good approach that I'm surprised more people don't use. It may not be immediately clear for some novices, but it's not any more cryptic than the rest of perl. Plus, if you're like me OP, I bet you "snip" off the really useful do blocks into full blown subroutines. This sort of thing seems perfectly natural to me.

Adbot
ADBOT LOVES YOU

Cylon Dinner Party
Dec 2, 2003

bored now.

blackoutdonnie posted:

This. It's a good approach that I'm surprised more people don't use. It may not be immediately clear for some novices, but it's not any more cryptic than the rest of perl. Plus, if you're like me OP, I bet you "snip" off the really useful do blocks into full blown subroutines. This sort of thing seems perfectly natural to me.

It does appear to be a valid technique. I've seen several examples of it in perldoc and perl design patterns, but that doesn't leave me any less disgusted with it. He could(and should) accomplish the same task by a) writing it all on one line without the temp variables, b) returning an anonymous sub, c) branching into a normal sub.

I'm assuming this is a trick for one-time insertion into someone else's code. I'd love to see a full page of do blocks in a new script.

floWenoL
Oct 23, 2002

ryan__ posted:

It does appear to be a valid technique. I've seen several examples of it in perldoc and perl design patterns, but that doesn't leave me any less disgusted with it. He could(and should) accomplish the same task by a) writing it all on one line without the temp variables, b) returning an anonymous sub, c) branching into a normal sub.

I'm assuming this is a trick for one-time insertion into someone else's code. I'd love to see a full page of do blocks in a new script.

I don't understand the vehement reaction to this. Writing it all on one line is infeasible for more complex examples, the anonymous sub does the same thing but with more syntactic noise, and branching it off into a normal sub should only be done if the same code is used in multiple places or it does a distinct conceptualizable task. I can certainly see a whole page of do blocks if you're doing a bunch of distinct steps, each of which isn't worth decomping into a separate function.

Nevergirls
Jul 4, 2004

It's not right living this way, not letting others know what's true and what's false.

Twlight posted:

This is what I have so far, it cut down a lot of the txt that I didn't need. now each line has this format
code:
ip adress<tab>ws-username(this is the info i want)<tab>unused info

here is my code

open(FILE,"pso.txt");
@arr = <FILE>;

open(NEWFILE,">newfile.txt");
foreach $line(@arr)
{
	if($line =~ m/.ws\-/i)
		{
			print NEWFILE $line;
    }
You're halfway there.
code:
perl -wne "print if /.ws\-/i" <pso.txt >newfile.txt
Learning Perl's defaults and command line options is important because it saves work.

Nevergirls fucked around with this message at 09:35 on Oct 31, 2007

IcePotato
Dec 29, 2003

There was nothing to fear
Nothing to fear
i loving hate perl right now. it's mysteriously eating up variables and things that worked fine at 2 am are now broken. this is a last resort for me.

e: problem solved for now

This is a script that takes in some symbol table information and a C source file, then attempts to output a html file with anchors at variable declarations and links to the declaration whe'er a variable is used. With scoping, which is why the control structure is so hosed up - you need to check the scope of every single variable used and select the variable from the closest scope. It's gone from "working almost perfectly" to "completely broken" after like 2 lines of code, and I'm a huge jackass who doesn't use repositories or version control. Right now, the highlighted line doesn't print at all even though it should - it certainly printed before, with no changes to the symbol table or source code. On top of that, we need to sometimes strip the last character because it correctly states that "array" != "array[]" even though we need tags around "array[]".

any advice? I swore i understood perl scoping and everything, but apparently i don't.

also is there any way that that giant if statement below the highlighted line has side effects I don't know about? I used identical nested if statements to get some debug messages and when I tried to replace that huge one with nested ones, things mysteriously stopped working.

edit: gently caress I FORGOT TO USE \S INSTEAD OF S

IcePotato fucked around with this message at 19:10 on Nov 9, 2007

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

IcePotato posted:

edit: gently caress I FORGOT TO USE \S INSTEAD OF S

So, problem solved? On the aside, something about your Perl doesn't jive with me... It might be something completely superficial like "I didn't write it". Do you have any inputs I could run it against?

IcePotato
Dec 29, 2003

There was nothing to fear
Nothing to fear

Triple Tech posted:

So, problem solved? On the aside, something about your Perl doesn't jive with me... It might be something completely superficial like "I didn't write it". Do you have any inputs I could run it against?

i'm im'g you about this because to be honest this is a school assignment and last thing I need is a TA wondering why my code is all over the internet, if anyone else is interested I will also talk to them about it in private

Subotai
Jan 24, 2004

How do I get info about filesystems in Perl? There is a statfs call but no statvfs call, etc.

floWenoL
Oct 23, 2002

Subotai posted:

How do I get info about filesystems in Perl? There is a statfs call but no statvfs call, etc.

Call df and parse its output? v:)v I'm sure there's a module like that in CPAN, too.

Stabby McDamage
Dec 11, 2005

Doctor Rope

Subotai posted:

How do I get info about filesystems in Perl? There is a statfs call but no statvfs call, etc.

Filesys::Df.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Let's say I have a super class and a program that's supposed to handle N sub classes of that... Is there a way to load all of those based on their existance on the file system, and not hard code use statements somewhere?

Super class Fruit. Sub classes Apple, Orange, Strawberry, and whatever else I happen to include on the file system...

npe
Oct 15, 2004

Triple Tech posted:

Let's say I have a super class and a program that's supposed to handle N sub classes of that... Is there a way to load all of those based on their existance on the file system, and not hard code use statements somewhere?

Super class Fruit. Sub classes Apple, Orange, Strawberry, and whatever else I happen to include on the file system...

You can use require to do this if you specify the file name, assuming you know the file names you're looking for. We dynamically load in modules based on command line arguments, which sounds similar to what you're talking about, in that we don't know until run time what we want to load. The idea is, given --class=Foo::Bar, we want to "use Foo::Bar". To do this we have to do something like:

code:
    my $classfile = $class.'.pm';
    $classfile =~ s/::/\//g;

    require $classfile;

    my %versions = Class::ISA::self_and_super_versions($class);

    if (!exists($versions{'Fruit'})) {
      die "$class is not a fruit!";
    }   

    my $instance = $class->new();
    $instance->go();
I'm not sure if that helps or not. It seems like you would be looking on disk for a file to exist, and if it does, doing something like the above to import it.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Wow, that was fast. How about to determine if a module is already used?

Ninja Rope
Oct 22, 2005

Wee.
You can look at %INC to figure out which modules are in use.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
What are my alternatives for the following?

code:
sub getMessage {
        my $self = shift;

        eval('$' . ref($self) . '::message');
}
This is a method off of the base class, whose mechanism never changes, but the source of the data does, it's class data, not instance data. What's a better way of writing this?

npe
Oct 15, 2004
The "official" method in the camel book is something like

code:
 sub getMessage {
   my $self = shift;
   my $class_func = ref($self).'::message';
   
   no strict 'refs';
   $class_func->();
 }
It's still ugly but at least you're not forcing a string eval.

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Classes and method names can be strings or subrefs, you don't need to result to ugly poo poo like eval or disabling strict.

code:
sub callMethod {
  my ($self) = @_;

  # instance method
  my $method = "method";
  my $result1 = $self->$method;

  # class method
  my $class = ref($self);
  my $result2 = $class->$method;

  # You can also...
  my $sub1 = sub { "hay $_[0]" };
  my $sub2 = \&method2;

  my $hay = $self->$sub1;
  my $itsa = $self->$sub2;
}

sub method2 {
  "it's a $_[0]";
}

npe
Oct 15, 2004
That's not exactly what he had asked and if the function is not expecting the classname to be passed in as $_[0] then he's going to have problems, although I do prefer those solutions if it's possible to do so.

Edit to clarify: if he has the following sub declared in package Foo:

code:

 sub message
 {
   my $text = shift;

   # do something with the message
 }

And he does this:

code:

 my $class = ref($self);
 $class->message('hello!');

...then he's passed in 'hello!' as $_[1] and 'Foo' as $_[0]. This is probably not what was intended.

npe fucked around with this message at 02:12 on Nov 15, 2007

Ninja Rope
Oct 22, 2005

Wee.
How's this?

code:
#!/usr/local/bin/perl

use warnings;
use strict;

package a;

sub a {
 die "@_";
}

package main;

sub {
 my $package = 'a';
 my $function = 'a';
 @_ = ( 'welcome', 'to', 'a::a!' );
 goto \&{"${package}::$function"};
}->();

leedo
Nov 28, 2000

Not exactly a question, but I thought someone might get a kick out of it...

Here is a horrible "IMAP to Google Calendar" program that I wrote last night. I thought it might help me in filling out my time sheets at work. Turns out that it is completely useless!

npe
Oct 15, 2004

leedo posted:

Not exactly a question, but I thought someone might get a kick out of it...

Here is a horrible "IMAP to Google Calendar" program that I wrote last night. I thought it might help me in filling out my time sheets at work. Turns out that it is completely useless!

You may want to remove your login and password from that...

leedo
Nov 28, 2000

Satan's Scallion posted:

You may want to remove your login and password from that...

God damnit, why do I always do stupid poo poo like this late at night. :(

ashgromnies
Jun 19, 2004
Here's an interesting problem someone brought up to me...

He needs to trigger a long-running process via an HTTP request. Since the HTTP request will time out before the process is done, he needs it to run in the background, then have an additional script report on its status.

What I was thinking was fork()ing in the method the HTTP request calls, which would allow the original HTTP method to continue, right?

Then create another method that polls the forked process and have the HTML call that via AJAX and report on the status of the process.


Any ideas? I'm not sure I understand how fork() works correctly, my C/Systems Programming Concepts professor was pretty terrible.

Won't fork() duplicate the entire process the HTTP request runs on, though? So that can't be the right way... hoark.

edit: ooh maybe http://www.stonehenge.com/merlyn/LinuxMag/col39.html

ashgromnies fucked around with this message at 22:28 on Nov 16, 2007

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Uhh, what? That sounds way too confusing.

The HTTP request would just be a touch and go on the server to start the process. Subsequent HTTP requests via Ajax would hit a process that's in charge of monitoring the status of the first, longer running process. And... that's it. There's no forking anywhere in this design.

more falafel please
Feb 26, 2005

forums poster

Triple Tech posted:

Uhh, what? That sounds way too confusing.

The HTTP request would just be a touch and go on the server to start the process. Subsequent HTTP requests via Ajax would hit a process that's in charge of monitoring the status of the first, longer running process. And... that's it. There's no forking anywhere in this design.

Or, if you don't want to have to learn about Ajax, the first HTTP request can just kick it off and send you to a page that monitors the status of the job, with auto-refreshes every so often.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
code:
use warnings FATAL => 'all';
warn "hello";
print "doof";
Is the function warn supposed to throw a fatal exception there and prevent the display of "doof" (it prints when I run it), or is the fatality given by use warnings only apply to warnings::warns?

npe
Oct 15, 2004
It looks like it doesn't affect the builtin warn(), however if you want to make all warnings die you can pretty safely trap the __WARN__ signal as recommended in the camel book:

code:
[~] $ cat foo.pl
 $SIG{__WARN__} = sub{die shift};
 warn "foo!";
 print "hi!\n";
[~] $ perl foo.pl
foo! at foo.pl line 2.
[~] $ 

InvSqrt
Nov 30, 2007
I want to start using my Perl knowledge for web development.

What's the best way to do this using Apache?
And what special stuff do I need to do in Perl to get this to work? I remember trying this once before and couldn't even get output to work.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
I'm sorry I don't know how to answer your question, but if you would like a roadmap of using Perl in web development in terms of making yourself more marketable to Perl jobs, I could suggest stuff for that.

1) mod_perl. To this day I'm still not sure what it does in that I haven't done anything with it myself.

2) Frameworks. I guess Catalyst would be a good choice.

3) Templating engines. Mason is pretty popular.

Looking up documentation for these might help you with your original question, since they're all interrelated.

syphon^2
Sep 22, 2004

InvSqrt posted:

I want to start using my Perl knowledge for web development.

What's the best way to do this using Apache?
And what special stuff do I need to do in Perl to get this to work? I remember trying this once before and couldn't even get output to work.
I was in your same position a while back. I learned Perl for my job, and I started having an interest in Web-Programming. I didn't want to pick up a new language, so I looked into what I could do with Perl...

1) Set up Apache (I use IIS myself) to work with CGI (you can google this)
2) Create a perl file with "use CGI ':standard';" at the head. Save as *.cgi
3) Read the documentation on CGI.PM.

I started out writing really simple apps. A single .cgi file with a simple HTML form that executed certain code based on how the user filled out the form. After that, I got more complex, adding in a Templating system and working under an MVC style.

Personally, I recommend starting out making a flat .cgi file that handles everything. Get comfortable with what CGI can do, and how to write it. Then expand towards using mod_perl or Templates or whatever you like.


EDIT:

Triple Tech posted:

1) mod_perl. To this day I'm still not sure what it does in that I haven't done anything with it myself.

2) Frameworks. I guess Catalyst would be a good choice.

3) Templating engines. Mason is pretty popular.
1) I'm not too knowledgable on mod_perl, but I installed it and tried it out. I think the big thing is that CGI loads the Perl interpreter independently with each call to a CGI page, while mod_perl keeps it loaded and just serves the page at request. It saves CPU cycles and makes the app run faster.

2) Catalyst is a pretty big framework. Personally, I found the overhead to be HUGE. I'd use this if I were developing some HUGE perl web-app, but otherwise, I'd avoid it. I installed it and played around, and after a few hours, I was still really far from actually getting anything done.

3) I personally recommend Template Toolkit (recommended to me by another goon). It works well for my needs.

syphon^2 fucked around with this message at 15:00 on Dec 6, 2007

leedo
Nov 28, 2000

syphon^2 posted:

1) I'm not too knowledgable on mod_perl, but I installed it and tried it out. I think the big thing is that CGI loads the Perl interpreter independently with each call to a CGI page, while mod_perl keeps it loaded and just serves the page at request. It saves CPU cycles and makes the app run faster.
In addition to that, mod_perl also gives you access to the entire apache request cycle. This lets you do things like URL rewriting with perl. You can also configure Apache itself with mod_perl, which I have found to be a godsend for setting up shared hosting environments.

quote:

2) Catalyst is a pretty big framework. Personally, I found the overhead to be HUGE. I'd use this if I were developing some HUGE perl web-app, but otherwise, I'd avoid it. I installed it and played around, and after a few hours, I was still really far from actually getting anything done.
Granted Catalyst has a lot of dependencies, but just like any other framework once you pick it up you'll be able to pump out web apps much faster.

I agree that starting with plain CGI scripting is best, simply so you can learn why frameworks like Catalyst exist.

ashgromnies
Jun 19, 2004

more falafel please posted:

Or, if you don't want to have to learn about Ajax, the first HTTP request can just kick it off and send you to a page that monitors the status of the job, with auto-refreshes every so often.

Yes but our Apache server is configured to kill the HTTP request after 30 seconds. The job to be executed takes longer than that.

InvSqrt
Nov 30, 2007
Thanks guys.
For the record, here's what I did to get it working:

1. apt-get install libapache2-mod-perl2
2. Found some example config and added it
code:
<Files ~ "\.pl$">
  SetHandler perl-script
  PerlResponseHandler ModPerl::PerlRun
  Options +ExecCGI
  PerlSendHeader On
</Files>
3. Created an index.pl containing this:
code:
#!/usr/bin/perl
use CGI;
print "Content-type: text/html\n\n";
print "<h1>Hello World!\n";

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
That's a great start. And for learning, CGI is a good place to be. But keep in mind that as you become a more experienced developer, you will begin to look at CGI.pm and be like... Wow, why did anyone write this.

Again, for where you are now, it's appropriate. Down the road, it will become less and less useful and more wtf.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
I'm inheriting this Perl script at work that's just so :psyduck: overwhelming every time I look at it. It really was written in a different era and just lacks any sort of modern idioms. It currently runs in production on Windows and I'm tasked with making it run on Linux. I would run-crash-edit run-crash-edit this until my eyes bleed except for the fact that it works with sensitive data and writes out to a production area. Essentially, there's no test environment set up and/or running it had side effects.

So I see two ways of attacking this. One, rewrite it from scratch, using the existing script as a spec. Two, check in the existing script and start pairing it down by refactoring idioms into it and deleting unnecessary code.

Thoughts? I'm just aggravated there's no sexy way to do this.

Edit: I've decided on using both approaches. I will write the script from the ground up, but I will also check in a dummy copy of the Windows script and start paring it down.

Triple Tech fucked around with this message at 23:24 on Dec 6, 2007

syphon^2
Sep 22, 2004

InvSqrt posted:

Thanks guys.
For the record, here's what I did to get it working:

1. apt-get install libapache2-mod-perl2
2. Found some example config and added it
code:
<Files ~ "\.pl$">
  SetHandler perl-script
  PerlResponseHandler ModPerl::PerlRun
  Options +ExecCGI
  PerlSendHeader On
</Files>
3. Created an index.pl containing this:
code:
#!/usr/bin/perl
use CGI;
print "Content-type: text/html\n\n";
print "<h1>Hello World!\n";
Awesome. That's exactly where I started. I advise your next step being...

1) Write a more complex index.pl that utilizes a form to gather input and then do something with that input.
2) Maybe play around with a few different types of forms, making more complex pages.
3) Use a templating system to separate out your HTML and Perl code
4) Use a full blown framework.
5) Take over the world.

Then again, I'm only somewhere between steps 3 and 4 myself. :)

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
I've found CGI::Application is a good midway point between CGI.pm and Catalyst. Plus the tools like CAP::ValidateRM and CAP::FillInForm make easy work of boring, important things like input validation. It's even super easy to AJAXify the application if you bolt in CGI::Ajax or use a toolkit like Prototype or Ext.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
You'll definitely want to move to a real framework eventually. I recommend Jifty, but I may be biased: I'm one of its developers. :) I haven't used Catalyst enough to draw a fair comparison, but what I do know is that Jifty (like Rails) is a full-stack framework. We give you a lot of what you'll need out of the box. Catalyst goes a different way, I guess they make it easy to plug in any modules you already have.

mister_gosh
May 24, 2002

I have a question. I have a filehandle I'm printing to:

code:
open(OUT, ">C:/example.txt");
...
print OUT "something";
...
close OUT
If someone CTRL-C's this script, nothing gets put in to C:/example.txt. Is there a way to ensure it closes properly or a better way of doing this?

Edit: thinking about this some more, is there a way to do something like if a user does CTRL-C or if there is an abrupt end or big error, can the program say "on exit, close this file handle?"

mister_gosh fucked around with this message at 14:06 on Dec 7, 2007

Adbot
ADBOT LOVES YOU

syphon^2
Sep 22, 2004

SpeedFrog posted:

It's even super easy to AJAXify the application if you bolt in CGI::Ajax or use a toolkit like Prototype or Ext.
Ooh, CGI::Ajax looks super easy to use, and I'd like to utilize it to implement some Ajax functionality in a web-app I have.

However, it doesn't look like it really works with Templating systems. It wants to create the html through it's build_html() method, which doesn't work with any templating systems I see.

Any ideas how I can combine the two?

EDIT:
It looks like CGI::Ajax has other methods to use in case you don't want it to render the HTML. However, it still doesn't work. Here's my sample page. It tries to use Template Toolkit in conjunction with CGI::Ajax. Feel free to try it yourself.

EDIT2: Hmmm, it apears that the Ajax works simply by invoking the CGI script again with a set of parameters, so that the CGI itself returns ONLY the value determined by the function. Maybe if I add some logic to detect those parameters, and bypass the rest of the page if they're included?

EDIT3: I got it working. There's not as much documentation available out there as I'd like... but I found someone who got it working. It turns out I need to use a third parameter in $template->process to output the HTML to a scalar, rather than straight to STDOUT. Then, I use CGI::Ajax's build_html method to output the HTML instead.

syphon^2 fucked around with this message at 18:04 on Dec 7, 2007

  • Locked thread