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
Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
IO::Tty::Constant is automatically generated when you install IO::Tty. Oops. IO-Tty's Makefile.PL has some doc.

You would need to include some sort of install step after all, unless all of these systems are identical and you can just include the autogenerated IO::Tty::Constant.

That Bundle::Expect module doesn't actually contain anything. Bundle:: modules just list the names of other modules. An example of a useful Bundle (unlike Bundle::Expect) is Bundle::CPAN, which lists of bunch of modules that cpan can use to be generally better.

Adbot
ADBOT LOVES YOU

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:
Probably a hyper-dumb question, but anyway. I'm converting a really old Perl app to PHP. I know next to nothing about Perl, but nevertheless everything was coming along smoothly until this line:
code:
    $$a{'000', 1} = $lea;
How would I translate that?

Edit: here's the whole sub, for context:
code:
sub parse_leader {
    my($lea, $a, $base) = @_;

    $$a{'000', 1} = $lea;

    $$a{"STA"}    = substr($lea, 5,  1);
    $$a{"TYP"}    = substr($lea, 6,  1);
    $$a{"LEV"}    = substr($lea, 7,  1);
    $$a{"CHA"}    = substr($lea, 9,  1);
    $$base        = substr($lea, 12, 5);
    $$a{"ENC"}    = substr($lea, 17, 1);
    $$a{"DES"}    = substr($lea, 18, 1);
    $$a{"LINK"}   = substr($lea, 19, 1);
}

Tad Naff fucked around with this message at 08:15 on Mar 4, 2009

Toe Rag
Aug 29, 2005

Kind of a guess but $a holds a hash ref and whatever is in $lea will be put into $a with the key of '01'

code:
perl -MData::Dumper -e '$lea=[qw(1 2 3 4 5 6)];$$a{'000', 1} = $lea;print Dumper $a'
$VAR1 = {
          '01' => [
                     '1',
                     '2',
                     '3',
                     '4',
                     '5',
                     '6'
                   ]
        };
I don't know how you'd translate that into PHP, though

There Will Be Penalty
May 18, 2002

Makes a great pet!

FeloniousDrunk posted:

code:
    $$a{'000', 1} = $lea;

Read the perlvar(1) documentation under $;.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
My boss is asking me to present on the most modernest poo poo, as suggestions for a new project. Given a fresh start, I'm thinking at bare minimum Moose (I know this makes Sartak happy) and Catalyst. I guess we're missing an ORM. DBIx::Class, maybe? Thoughts?

Triple Tech fucked around with this message at 20:25 on Mar 4, 2009

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Yeah, use DBIx::Class. There are other options (Fey::ORM, KiokuDB) but I don't think they're ready for general use yet.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
I've come to love Rose::DB over the past few months.

Tad Naff
Jul 8, 2004

I told you you'd be sorry buying an emoticon, but no, you were hung over. Well look at you now. It's not catching on at all!
:backtowork:

There Will Be Penalty posted:

Read the perlvar(1) documentation under $;.

Got it.
code:
$$a{'000',1}=$lea;

is
php:
<?
$a['000'][1]=$lea;
?>
Thanks!

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
The wheels have been set in motion. I recommended DBIx::Class, Moose, Catalyst, and HTML::Mason.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Building Rakudo (Perl 6 on Parrot) from scratch is now four steps:

code:
git clone git://github.com/rakudo/rakudo.git
cd rakudo
perl Configure.pl --gen-parrot
make
That third command gets a checkout of Parrot and builds it, so you don't even need to bother with setting Parrot up any more.

Try it out!

leedo
Nov 28, 2000

I'm starting a new project at work and I am looking for a web framework with a more lightweight install than Catalyst. I have a lot of experience with Catalyst, and it would actually work really well for this, but I'm afraid the massive list of CPAN dependencies will scare away the higher-ups.

I'm looking at CGI::Application right now. I have a rather large DBIx::Class schema, so it is nice that it can be used as a mod_perl handler (presumably not reloading the schema on each request.)

Any other suggestions? The trend around here has been to roll their own frameworks, but hopefully I can steer them in the direction of Catalyst eventually.

edit: on second thought, gently caress it, all the Catalyst modules I need are in Debian already so the install is not going to be painful.

leedo fucked around with this message at 02:09 on Apr 21, 2009

leedo
Nov 28, 2000

YAPC tickets are on sale at a big discount this week. I picked some up, though I'm not 100% sure I can make it. At the very least it is a decent donation.

http://yapc10.org/yn2009/

nitrogen
May 21, 2004

Oh, what's a 217°C difference between friends?
First off, I'll admit for not searching, cuz, well, search is just temporarily down.

I am not much of a perl person, I'm just starting out.

I am trying to write a routine in a perl script to parse an XML file.

The XML is basically like this:

code:
<LoadProfileEventTypeList>
  <LoadProfileEvents>
    <LoadProfileEventType>
        <Name>WATERHEATER</Name>
        <KW1up>5.46</KW1up>
        <KW1down>5.46</KW1down>
        <Status>ON</Status>
    </LoadProfileEventType>
    <LoadProfileEventType>
        <Name>AIRCOND</Name>
        <KW1up>3.57</KW1up>
        <KW1down>3.57</KW1down>
        <Variation>10</Variation>
        <Status>OFF</Status>
    <LoadProfileEventType>
</LoadProfileEventTypeList>
I'm trying to write the code to smartly handle additional "<LoadProfileEvents>" that arent' specified here (i.e. not key off of these named ones specifically, but any others that may be added or removed in the future)

What I need to be able to do, in "psuedocode":
for each <LoadProfileEventType> where <Status> = YES print <NAME>

And I have no idea how to go about doing this.

I'm using XML::Simple to read the xml data.

2.7182818284590
Dec 10, 2004

lol custom title more like custom DICKS

nitrogen posted:

And I have no idea how to go about doing this.

code:
for my $event (@{$xmlref->{LoadProfileEvents}->{LoadProfileEventType}}) {
	print "$event->{Name}\n" if ($event->{Status} eq 'ON');
}
Is this what you were thinking of?

nitrogen
May 21, 2004

Oh, what's a 217°C difference between friends?
That's exactly it. Thanks. I was doing the bits for nested tags in XML::Simple incorrectly.

wolffenstein
Aug 2, 2002
 
Pork Pro
Speaking of XML, I can't figure out how to retrieve the correct data of the original reference from another reference.

XML:
code:
<server>
 <address>production1</address>
 <host>www.example1.com</host>
 <host>www.example2.com</host>
</server>
<server>
 <address>production2</address>
 <host>www.example3.com</host>
 <host>www.example4.com</host>
</server>
Perl:
code:
my $xml = XMLin($configurationXML, ForceArray => [ qw(server host) ], KeyAttr => []);

foreach my $server (@{$xml->{server}){
 foreach my $host (@{$server->{host}){
  # example
  $hostConfContents .= "LogFile=\"$xml->{localLogDirectory}/$server/$host/apache-access.log\"\n";
 }
}
Output:
code:
LogFile="/srv/stats/log/HASH(0x85cd8bc)/www.example1.com/apache-access.log"
Edit: I realized I was referencing the wrong information. For future help look at this code:
code:
my $xml = XMLin($configurationXML, ForceArray => [ qw(server host) ], KeyAttr => []);

foreach my $serverRef (@{$xml->{server}){
 my $server = $serverRef->{address};
 foreach my $host (@{$serverRef->{host}}) {
  # example
  $hostConfContents .= "LogFile=\"$xml->{localLogDirectory}/$server/$host/apache-access.log\"\n";
 }
}
Second edit: this code works perfectly.

wolffenstein fucked around with this message at 23:59 on Mar 17, 2009

Beardless Woman
May 5, 2004

M for Mysterious
Use Data:: Dumper to dump out the contents of $xml->{localLogDirectory} to see why it's coming up as a Hash.

Erasmus Darwin
Mar 6, 2001

Beardless Woman posted:

Use Data:: Dumper to dump out the contents of $xml->{localLogDirectory} to see why it's coming up as a Hash.

I don't think localLogDirectory is coming up as a hash. It looks like that's getting expanded to "/srv/stats/log". It's the next variable in the string, $server, that seems to be the hash reference.

wolffenstein, are you sure that the corrected code that you posted still produces the wrong output? It looks like the incorrect version that you first posted would be exactly the sort of mistake that would produce the bad output in question.

If your corrected version's still causing problems, Data::Dumper's the way to go as Beardless Woman suggested. I'd recommend doing the dump on $serverRef to get the full picture.

Erasmus Darwin fucked around with this message at 21:18 on Mar 17, 2009

wolffenstein
Aug 2, 2002
 
Pork Pro
I didn't make clear the second perl snippet works as intended. Thanks for your help.

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Moose question for Sartak.

Let's say I have a DESTROY that's paired with a side effect during the object's construction. In traditional Perl, if the side effect fails, the object doesn't have to be constructed, and DESTROY isn't called later.

But in Moose, if I delegate the side effect to the BUILDer, it's possible that the object is constructed in Perl space but BUILD can still fail. When Perl tears everything down, it calls on a mismatched DESTROY.

Is this what DEMOLISH is for? I just tested it and die'ing from BUILD still triggers DEMOLISH. I would have thought DEMOLISH would be paired with a successful BUILD.

use Please::Advise;

Edit: Hrmm... I'm reading the Moose source and I guess since DESTROY is used BY Moose, I need to make a destructor in Moose-space, they're asking me to use DEMOLISH instead, which is fine. But I don't think you're taking into account this mismatched BUILD-DEMOLISH scenario. Thoughts?

Triple Tech fucked around with this message at 22:54 on Mar 19, 2009

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
DEMOLISH is like BUILD in that it is called for each class in your hierarchy. You don't need to worry about calling the right "next" method (which can be weird under multiple inheritance). Moose takes control of the DESTROY method. Moose's DESTROY calls DEMOLISH on every class in your hierarchy, just like Moose's new calls BUILD on every class in your hierarchy. These two special methods result in shorter (and more correct!) code.

There are two ways to fix your design issue. You can add an attribute to indicate whether you successfully initialized, or you can do your initialization before new.

code:
has is_initialized => (
    is       => 'rw',
    isa      => 'Bool',
    default  => 0,
    init_arg => undef,
);

sub BUILD {
    my $self = shift;
    $self->setup;
    $self->is_initialized(1);
}

sub DEMOLISH {
    my $self = shift;
    return unless $self->is_initialized;
    $self->teardown;
}
init_arg => undef makes it so the code creating this object cannot pass in a value for is_initialized. If they accidentally do, then it would mess with your teardown step.

The other option is:

code:
before new => sub {
    my $class = shift;
    $class->setup;
};

sub DEMOLISH {
    my $self = shift;
    $self->teardown;
}
I don't like the latter because it then forbids Moose from making a special optimization -- inlining your constructor (which is where most of the speed boost from make_immutable comes from). It also means you have only the class, not the instance (though from your description it seems like that's how it was pre-Moose anyway). This works because your setup method can throw an error before your object is constructed, and so DEMOLISH (and DESTROY) won't be called.

The former kind of sucks in that it adds an attribute to your class, but oh well.

Filburt Shellbach fucked around with this message at 23:50 on Mar 19, 2009

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Hrm, I was more expecting you to say that Moose was designed wrong! I mean, philosophically, is an object considered complete only after BUILD? Or is it kinda superfluous and a Perl-object is good enough for a Moose object? Why wouldn't you check that BUILD was successful before deciding to DEMOLISH?

I guess if something was partially built you'd still want a thorough destructor... Ehh, I dunno.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
We try to avoid making those kinds of assumptions about what you are doing. When there are multiple valid options, it's sometimes nice to let the user decide.

I guess part of it is also that exceptions in BUILD are weird to begin with.

dizzywhip
Dec 23, 2005

I'm having trouble with get and post data in perl. Previously I was extracting arguments using the CGI module, as in $cgi->param($key). That was working fine with just get arguments, but I found out that if I had both post and get arguments it would only find the post args.

So I did some research and made a function that did it manually, but I ran into a problem with getting post data. All the information I found said to use read(STDIN, $request, $ENV{'CONTENT_LENGTH'}), but it fails every time.

So I guess I have three questions. Is there any way to get the CGI module to fetch both get and post arguments? And if not, what's wrong the method I'm using to extract post data manually? Lastly, will I even be able to grab both get and post data this way? I was assuming I'd be able to concatenate the post and get data and then process them normally.

Land Mime
Jul 13, 2007
Love never blows up and gets killed

mit_senf posted:

I'm having trouble with get and post data in perl. Previously I was extracting arguments using the CGI module, as in $cgi->param($key). That was working fine with just get arguments, but I found out that if I had both post and get arguments it would only find the post args.

So I did some research and made a function that did it manually, but I ran into a problem with getting post data. All the information I found said to use read(STDIN, $request, $ENV{'CONTENT_LENGTH'}), but it fails every time.

So I guess I have three questions. Is there any way to get the CGI module to fetch both get and post arguments? And if not, what's wrong the method I'm using to extract post data manually? Lastly, will I even be able to grab both get and post data this way? I was assuming I'd be able to concatenate the post and get data and then process them normally.

http://perldoc.perl.org/CGI.html#MIXING-POST-AND-URL-PARAMETERS

dizzywhip
Dec 23, 2005


Thanks

adante
Sep 18, 2003
edit: am moron accidentally pressed tab + space, still writing this now..

far out.

I wrote a module based on JSON::RPC to publish some json encoded data. It originally had a layout like this:

code:
use strict;
use warnings;
use DBI;

package MyPackage;

my $dbh = DBI->connect(...);

sub foo : Public {
  my ($s, $x) = @_;

  $dbh->do(...);
}
Unfortunately it starts throwing (not in any particularly systematic manner, sometimes it does and sometimes it doesn't) this sort of error.

I don't quite understand what the problem is because I don't fully get the interactions between apache and mod_perl, but how I should deal with this?



adante fucked around with this message at 18:58 on Mar 22, 2009

wolffenstein
Aug 2, 2002
 
Pork Pro
code:
my $xml = XMLin($configurationXML, ForceArray => [ qw(server host) ], KeyAttr => []);

foreach my $serverRef (@{$xml->{server}){
 my $server = $serverRef->{address};
 foreach my $host (@{$serverRef->{host}}) {
  # example
  $hostConfContents .= "LogFile=\"$xml->{localLogDirectory}/$server/$host/apache-access.log\"\n";
 }
}
Now I'm stuck figuring out how to push data into this hash reference. XML::Simple sets server and host tags as arrays. The best way I've found so far is create a new hash reference, copy the data and add data by having incremental variables before each foreach loop. Example code:
code:
my %newXMLhash;
my $newXML = \%newXMLhash;
$newXML->{localStorageDirectory} = $ref->{localStorageDirectory};
$newXML->{errorLog} = $ref->{errorLog};

my $i = 0;
foreach my $serverReference (@{$ref->{server}}) {
	$newXML->{server}[$i]{name} = $serverReference->{name};
	$newXML->{server}[$i]{operatingSystem} = $serverReference->{operatingSystem};
	$newXML->{server}[$i]{rsyncUser} = $serverReference->{rsyncUser};
	$newXML->{server}[$i]{hostConfLocation} = $serverReference->{hostConfLocation};
	
	my $j = 0;
	foreach my $virtualHostReference (@{$serverReference->{host}}) {
		$newXML->{server}[$i]{host}[$j]{name} = $virtualHostReference->{name};
		$newXML->{server}[$i]{host}[$j]{hostLocation} = $virtualHostReference->{hostLocation};
		$newXML->{server}[$i]{host}[$j]{hostAlias} = $virtualHostReference->{hostAlias};
		++$j;
	}
	
	++$i;
}

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I didn't see an actual question there, but you REALLY want to learn how to use push and pop. Your use of stuff like $i and $j is just atrocious.

wolffenstein
Aug 2, 2002
 
Pork Pro
So if I wanted to add a new virtual host to the server, I would push a hash with the host's information into the the hash reference at the {server}{host} level? And yes, I admit using incremental counters in a foreach loop is dumb as hell.

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?

adante posted:

Unfortunately it starts throwing (not in any particularly systematic manner, sometimes it does and sometimes it doesn't) this sort of error.
http://search.cpan.org/~timb/DBI/DBI.pm#Threads_and_Thread_Safety

At the moment you're creating your $dbh at compile time, since the instantiation takes place when the package is pulled in by mod_perl. If you create it at run-time closer to when it's needed, as opposed to at startup, the errors should stop occurring. You may still cache the handle between requests, however you need to make sure you connect after the thread itself is created (otherwise it will be shared between threads, and blow up when you use it).

The easiest way would be to make a get_dbh() function that connects the first time it's called, and just returns the existing handle every subsequent time.

Mario Incandenza fucked around with this message at 21:32 on Mar 22, 2009

mdxi
Mar 13, 2006

to JERK OFF is to be close to GOD... only with SPURTING

Sometimes, because perl tries to be so flexible, I'll get a horrible idea and just see if it works.

I have a nested datastructure, and wanted to know if a list -- which would always exist and have at least one element -- would have more than one element in it. The "sane" expression that I settled on is:

code:
if (defined $res->{cat}{slist}[1])
But before that, I decided to try this, just to see if the parser would do the right thing:

code:
unless ($#{@{$res->{cat}{slist}}} == 0);
It does :aaa:

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Just because you can doesn't mean you should. Why not:
code:
my $list = $res->{cat}{slist};

if (@$list > 1) {
}

adante
Sep 18, 2003

atomicstack posted:

http://search.cpan.org/~timb/DBI/DBI.pm#Threads_and_Thread_Safety

At the moment you're creating your $dbh at compile time, since the instantiation takes place when the package is pulled in by mod_perl. If you create it at run-time closer to when it's needed, as opposed to at startup, the errors should stop occurring. You may still cache the handle between requests, however you need to make sure you connect after the thread itself is created (otherwise it will be shared between threads, and blow up when you use it).

The easiest way would be to make a get_dbh() function that connects the first time it's called, and just returns the existing handle every subsequent time.

What's best practice? I have now changed it to something like:


package MyPackage;

my $dbh = null;

sub getdbh {
$dbh = DBI->connect(...) unless $dbh;
return $dbh;
}

sub foo : Public {
my ($s, $x) = @_;
my $dbh = getdbh();

$dbh->do(...);
}



This seems clunky and somewhat annoying to have to getdbh() in every call. I was reading the mod_perl manual and it suggests using the PerlRequire directive to use a file to startup - the next page uses Apache::DBI. But I've been told by others that Apache::DBI is evil. I have no idea about this, can someone give me pointers on what, if anything, is best practice?

hitze
Aug 28, 2007
Give me a dollar. No, the twenty. This is gonna blow your mind...

I'm not sure if this is the right place to ask, but can anyone help me with a problem buttbot is giving me?
Buttbot is goon made apparently http://code.google.com/p/buttbot/

Buttbot throws and error when it attempts to buttify something. The error is
code:
Can't call method "hyphenate" on an undefined value at Butts.pm line 85.
I've looked around on the google code site but couldn't find any information on properly setting it up :(

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
What revision of Buttbot do you have? And do you have TeX::Hyphen installed?

hitze
Aug 28, 2007
Give me a dollar. No, the twenty. This is gonna blow your mind...

I have r93 and TeX::Hypen is in my lib folder.

e: doing "perl -e "use TeX::Hyphen"" works fine

e2: i overwrote my TeX folder with the same files and now the bot works :psyduck:

hitze fucked around with this message at 02:27 on Mar 27, 2009

Fenderbender
Oct 10, 2003

You have the right to remain silent.

hitze posted:

I have r93 and TeX::Hypen is in my lib folder.

e: doing "perl -e "use TeX::Hyphen"" works fine

e2: i overwrote my TeX folder with the same files and now the bot works :psyduck:

Kind of pointless to mention it now, but you can use a module from the command line with perl -MTex::Hyphen

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?

Fenderbender posted:

Kind of pointless to mention it now, but you can use a module from the command line with perl -MTex::Hyphen

Well, he would have to have a shallow execute, like perl -MTeX::Hyphen -e 1.

Adbot
ADBOT LOVES YOU

wigga please
Nov 1, 2006

by mons all madden
Just started using Perl this week, so excuse any blatant stupidity please.

I was wondering how I could read from a SQL db to an array. This is my code so far:

code:
sub opponent_model(@pName)
{
	$dbh = DBI->connect('dbi:mysql:fpdb','statparser','statparser')
		or die "Connection Error: $DBI::errstr\n";
#	correct use of @pName in SQL string (interjection of string into string)
	$sql = 'SELECT SUM(HDs),SUM(street0VPI),SUM(street0Aggr),SUM(street1seen),
	SUM(foldToOtherRaisedStreet1),SUM(street1Aggr),SUM(street2seen),SUM(foldToOtherRaisedStreet2)
	,SUM(street2Aggr),SUM(street3seen),SUM(foldToOtherRaisedStreet3),SUM(street3Aggr),SUM(wonAtSd)
	,SUM(sawShowdown) FROM hudcache,players WHERE hudcache.playerId=players.id AND players.name='
	, \@pName, 'GROUP BY playerId';
	$sth = $dbh->prepare($sql);
	$sth->execute;
		or die "SQL Error: $DBI::errstr\n";
	$rawstats = $sth->fetchrow_array();
}
The internet told me I'm dumb for using $pName here, because in case $pName contains a hyphen SQL will go haywire over it. I've seen it replaced by a question mark but I don't know how to tell Perl to replace that question mark with $pName.
Also: will the last line of code effectively fill the array $rawstats with all data from the query? It's important here that the data remain in the order as read by the SQL statement.

  • Locked thread