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
Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

Although I do see the argument of "well, it's a module we developed internally, so we have to put it in our own namespace". True, but sometimes you create things that aren't really proprietary, or could easily be shared with the world.

Most any application/module/plugin developed at a company is going to be an IP, even small things like a slightly more specific text parser. Everywhere I've worked has used their own namespace, and even namespaces specific to each individual group. It just adds one more layer of structure, in my opinion, and I see no reason to be rid of the practice.

Adbot
ADBOT LOVES YOU

Fenderbender
Oct 10, 2003

You have the right to remain silent.

TiMBuS posted:

I use ubuntu. It's my fav distro and you cant change my mind >=(
However, it relies on the perl package provided for a lot of programs, so I can't uninstall it and manually build and install perl 5.10
I can only guess how long ubuntu will take to upgrade the perl package, but it probably won't be soon because they like to quadruple check the drat stuff they release has no bugs, plus they'll have to upgrade and repack all of their current packaged perl modules as well.

So, wat du I do? The only solution I can think of is making my own package and overriding the ubuntu one, but who knows how much stuff I could break doing that.. Maybe I should just wait?

What I did was do a source install to /opt/perl and just changed the shebang to #!/opt/perl/bin/perl. This is only temporary until 5.10 is made available for an upgrade.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

TiMBuS posted:

I don't really need it, I just really want it :3

I nearly went and installed perl over the top of the old one, but common sense prevailed and I instead installed it to /opt/.

Now to go abuse the crap out of 'say'.

Throw this at the beginning of a 5.8 script:
code:
$\ = "\n";
:3: This has been a life-saver in the past. Every print will have $\ appended to the end of it. So make $\ a newline and you effecively have 'say'.

Fenderbender fucked around with this message at 09:36 on Jan 15, 2008

Fenderbender
Oct 10, 2003

You have the right to remain silent.

TiMBuS posted:

Ah yeah, nearly forgot about local.
I mostly use local to undef $/ which makes it faster to glob through files.

But it's not exactly a convenient workaround to locally scope $\ just to add an automatic newline.

In the end I guess I just like say.

Say is definitely really cool, have you seen Perl6::Say? :3:

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Mustach posted:

Any clues to what could be causing this?
code:
Net::SSLeay object version 1.30 does not match bootstrap parameter 1.25 at
    /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 251, <DATA> line 225.
Compilation failed in require at
    /usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/SSL.pm line 17, <DATA> line 225.
BEGIN failed--compilation aborted at
    /usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/SSL.pm line 17, <DATA> line 225.
Compilation failed in require at
    /usr/lib/perl5/vendor_perl/5.8.8/Net/LDAP.pm line 156, <DATA> line 225.
Line 17 is just
code:
use Net::SSLeay;
so I don't know where the 1.25 parameter to bootstrap could be coming from. I've tried changing it to
code:
use Net::SSLeay 1.30;
but get the same error. Both Net::SSLeay and Net::LDAP are the latest, RedHat-supplied versions for i386. I'll appreciate even the slightest guesses toward a solution.

The only thing I can guess is that you have shared objects with mismatched versions?

Fenderbender
Oct 10, 2003

You have the right to remain silent.

:froggonk: That modules like a disfigured orphan. Horrifying and depressing at the same time.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Among a bunch of other things, you should concatenate with a period (.) not a comma (,) so the first I'm going to say is to replace:

open $out, ">", "$log_dir$csvfile";

with: open $out, ">" . "$log_dir$csvfile";

if not: open $out, ">$log_dir$csvfile";

or even better: open($out, '>' . $log_dir . $csvfile);

Couple of suggestions:

1. As has been said use strict; though I generally use #!/usr/bin/perl -w instead of use warnings; thought that's all a matter of taste.

2. If you're declaring variables as the same value (in this case, undefined), you can declare them like my ($foo, $bar, $baz) = 'whatever'; or just my ($foo, $bar, $baz);

3. Also, another useful thing to use for getting a file list is glob() so instead of
code:
opendir $csvdir, $csv_dir;
my @csvfiles = grep {!/^\./} readdir $csvdir;
closedir $csvdir;

opendir $logdir, $log_dir;
my @logfiles = grep {!/^\./} readdir $logdir;
closedir $logdir;
you could have
code:
my @csvfiles = glob("$csv_dir/*");
my @logfiles = glob("$log_dir/*");
It doesn't scale too well once you get into several hundred files, but it is very useful.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Just because I get some sick joy out of reformatting and condensing code, I took a swing (not that I've tested it, just really reformatted and changed a few things). Do not take this as a lesson in how to write code, this is more for me than it is for you, but it can give you some idea of how it can be done differently. Perl has a lot of stylistic measures that are purely preferential so don't think you're doing something wrong because I'm doing something slightly different. I agree with Triple Tech that we need to write a style guide.

code:
#!/usr/bin/perl -w

use strict;

use Data::Dumper;

my (@csva, @loga);
my ($csvdir, $logdir);
my ($csv_fh, $log_fh);
my ($csvline, $logline);
my ($csv, $log);
my $out

my $csv_dir = "/home/jnooraga/csvdir/";
my $log_dir = "/home/jnooraga/csvdir/logs/";

my @csvfiles = glob("$csv_dir*");
my @logfiles = glob("$log_dir*");

foreach my $csvfile (@csvfiles) {
    next if (-d "$csv_dir$csvfile");

    open($out, '>' . $log_dir . $csvfile);
    open($csv, '<' . $csv_dir . $csvfile);

    $csvline = <$csv>;

    while ($csvline = <$csv>) {
        chomp($csvline);

        @csva = split(',', $csvline);

        foreach my $logfile (@logfiles) {
            next if (-d "$log_dir$logfile");

            open($log, '<' . $log_dir . $logfile);
            my $logline = <$log>;

            while ($logline = <$log>) {
                @loga = split(',', $logline);

                if ($loga[0] eq $csva[2]){
                    for (my $j=0;$j<scalar(@csva);$j++){
                        print $out $csva[$j] . ',';
                    }
                    print $out '"' . $loga[13] . "\"\n";
                }
            }

            close $log;
        }
    }

    close $csv;
    close $out;
}
Just remember that there are a lot of little things you can do to make your code more readable, and in some cases can help clarify for the compiler.

Fenderbender fucked around with this message at 15:16 on May 14, 2008

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

I see you and I raise you. Untested. Main problems (with the original code) include not knowing interpolation/parsing tricks and excessive scope.

Though you condense the code, there is an amount of readability lost. If you're going for less lines, I think this would save you a few.

code:
            my $logline = <$log>; # shift off the first line containing headers
            while ($logline = <$log>) {
                my @loga = split ',', $logline;

                if ($log[0] eq $csva[2]){
		    print $out "$_," for @csva;
                    print $out qq~"$loga[13]"\n~;
                }
            }

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

I disagree, actually. I find that as a seasoned Perl guy (and not someone who just uses Perl on the side), less is more. I'm not saying it's a golfing contest. Clearly, I would have lost some strokes (and performance) by introducing those concept scalars. But the way the OP wrote it, those scalars tell you nothing of what business logic is going on. And poo poo like this always bubbles up and turns into maintenance nightmares.

My heuristic is as follows
* Write code the way it speaks to you in your head, with maximum inclusion of business concepts
* When possible, take away excessive punctuation/parenthesis
** If this rule introduces ANY sort of confusion or disambiguity, introduce punctuation and parenthesis tastefully

Obviously that last part will depend on the programmer, but I think shorter code is much more powerful and easier to understand than long code. Long code doesn't automatically mean good code.

Oh, I agree. That is pretty much what goes on in my head as I'm coding. I just see far too often people that have tried to do too much on one line that can be handled more concisely. I completely agree that your way is more concise, I guess I misunderstood what you were attempting to go for.

For example, just a few minutes ago I was able to bring 7 lines of someone else's code down to just 3 with a simple

open($fh_conf, $conf_file) or die "Couldn't open file $conf_file: $!\n";
my $conf_vars = { map { chomp;split('|') } <$fh_conf> };
close($fh_conf);


and lost little readability. I think we're mostly agreeing in different ways.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Erasmus Darwin posted:

I've got one minor quibble with this. I personally prefer moving the last / to when $csv_dir and $log_dir are used rather than sticking it in the config string:

code:
my $csv_dir = "/home/jnooraga/csvdir";
my $log_dir = "/home/jnooraga/csvdir/logs";

my @csvfiles = glob("$csv_dir/*");
my @logfiles = glob("$log_dir/*");
1) Invocations have a more natural looking "$dir/$file" style to them which mimics what they really are.
2) If someone changes the directories (especially if you were to move their definition to a config file or something), they won't shoot themselves in the foot regardless of whether or not they include a final slash (since an extra slash gets ignored but a missing slash causes everything to break).

Yes, I've put way, way too much thought into this.

Once again, I completely agree, I was more trying to reformat and clean than change values. I think I might start a Perl style guide thread in the next couple of days based on some of the stuff I've seen in this thread, if anybody would like that.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
It's a bit late so maybe I'm misunderstanding the discussion or the way it works, but to comment on the above code, => is just an alias for a comma. So when you declare a a hash, if you have (), it's essentially not putting an item in there. In the above example:
code:
my %hash = (
  foo => 1,
  bar => get_nothing(),
  baz => 2
);
is the same as

my %hash = ('foo', 1, 'bar', 'baz', 2);

You're placing an empty array as a value, so it's compiled as essentially just nothing, and so it offsets all the key/value pairs in the hash.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

yaoi prophet posted:

Sure, we know why it happens, but the point is that it's a gotcha that can cause problems due to the sneaky ways that list context will suddenly appear without you realizing it.

I consider it a gotcha because wantarray is precisely the sort of thing that is tempting to use when you need to retroactively modify an existing function that is already in use. "Man, I'd really like to have an array here instead of a string. Hey, I can just have that function check wantarray, and no one will ever know!" That's when everything breaks, because that function is being used in parameterized argument lists all over the place.

Well, that's how it happened to me, anyways. The moral of the story is: either don't use wantarray at all, or if you do, it's probably best to not retroactively add it to an existing sub unless you feel really good about your unit test coverage.

Now that I'm awake to compound more on this, there was an interesting issue that arose recently at my work which this list flattening is used for in a legitimate sense.

When trying to match "john", "jon", "johnathan", or "jonathan" from an array of first names using map (yes, I know grep is much more suited, but bear with me), the code my coworker was having issue with was something along the lines of

@names = qw(john jacob jeremy jon johnathan allan jonathan);
@names = map { /^joh?n/ } @names;


would return

['john', undef, undef, 'jon', 'johnathan', undef, 'jonathan']

Now, that's because you're returning a false/undefined value since the regex wouldn't match. What instead you needed to do was to use

@names = map { /^joh?n/ ? $_ : () } @names;

This will use that "sneaky" behaviour of lists to create:

['john', 'jon', 'johnathan', 'jonathan']

This was when I started to realize the usefulness of this behaviour. Thought it might be an interesting enough of an anecdote since it seemed relevant enough even if it's going over something glaringly obvious to most people.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Sartak posted:

While in general you're certainly right (map { ... ? ... : () } is useful), in this case your code can be written as:

code:
@names = grep { /^joh?n/ } @names;

Fenderbender posted:

(yes, I know grep is much more suited, but bear with me)

Fenderbender
Oct 10, 2003

You have the right to remain silent.

syphon^2 posted:

I don't know, it seemed that creating a new array and sorting it JUST for the sake of iterating through another hash in a certain manner (alphabetized) wasn't the best way to do things. I had no valid reasons to think so, I just wanted to make sure. :)

Well, as Tech said, you don't need to create a new array, just use

foreach my $key (sort keys %$data) {

Fenderbender
Oct 10, 2003

You have the right to remain silent.
I don't know if this would be an ok place for this or anything, but my company is looking for web and application developers specializing in Perl. If you're interested, send me a PM and I'll give you some contact information.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

Randomly curious, what city/metropolitan area are you located in?

It's in Nashville, TN

Mithaldu posted:

Could you please activate the ability for other members here to email you? I don't have PM ability, but if you can accept remote workers i'd be very interested. Or, if you don't want to do that, you could give my ICQ/AIM or Yahoo ids in my profile a poke.

I figure 3+ years on a life system should be decent experience for what you want. :)

Done. I'll also drop you an IM once I get to work.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
I typed this.

code:
$string = "racecar";

while ($string =~ s/^(.)(.*)\1$/$2/) {
  print "PALINDROME" if length($string) <= 1;
}
Edit: Kinda similar to heeen's, it would seem.

Fenderbender fucked around with this message at 22:12 on Nov 14, 2008

Fenderbender
Oct 10, 2003

You have the right to remain silent.
s/\\(.{8}).+(\\)/\\\1~1\2/g would work too I would think. Untested and off the top of my head.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Erasmus Darwin posted:

I think your regexp is still broken. Regardless, you need to check the file system to reliably determine a short name due to the possibility of naming collisions. If I make a root-level folder on C: called "Program Stuff", it'll wind up being Progra~2 due to Progra~1 being taken by "Program Files".

Ah, yes, completely forgot about that.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Sock on a Fish posted:

I've got a step in a script at which I need to see if two times are equal to one another. They come in as a UTC string, and I'm not sure which is quicker -- convert the string to an integer with str2time and compare the integers, or just use a string comparison on the twenty-odd character string. I can't just use time to test the two methods, since my data gets pulled from an external source that varies wildly in the amount of time it takes to return a query result.

Anyone know which is quicker?

If you're not worried about compile-time overhead, Date::Manip is good for such a thing.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Oh, I completely missed that it's coming in UTC format. I need to readed better.

Fenderbender
Oct 10, 2003

You have the right to remain silent.

atomicstack posted:

It's also a handy idiom if you want to merge two hashes:
code:
  my (%left, %right);
  @left{keys %right} = values %right;

gently caress! I could've used this many times before!

Fenderbender
Oct 10, 2003

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

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

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

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

You don't need to execute anything, just using the -M flag will compile the module and will drop an error if it doesn't compile properly or isn't found. It will however sit around indefinitely if it successfully compiles, so yeah.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Hahaha, when I started using Perl I got into an argument with merlin on PerlMonks about sorting algorithms, unbeknownst to me that merlin = Randall Schwartz. :v:

Fenderbender
Oct 10, 2003

You have the right to remain silent.

SA Support Robot posted:

Does anyone here use AnyEvent? I am madly in love with it and wish to project my love upon others.

:swoon:

That's pretty cool. For curiosity's sake, what has been your greatest use for it so far?

Fenderbender
Oct 10, 2003

You have the right to remain silent.
I'm getting into Moose and I am looking to make a simple object for a User, but I'm not sure the best way to go about implementing Rose::DB::Object into it. Would anyone be willing to throw me a few pointers on where to start?

Fenderbender
Oct 10, 2003

You have the right to remain silent.

atomicstack posted:

Where are you going to be using this user class? If I were doing it in Catalyst, for example, I'd create a new model which consumes the RDBO schemas and loads the row from the database on your behalf, before packing it into the attribute of a Moose object and returning that. Then you call high level methods on the Moose object and it operates on your RDBO row under the hood.

I'm writing it for use within my own framework. The current method I've gone about it is as such, though I plan on expanding the fields that 'rose' handles out to include all of the row's fields. Possibly I'll be doing that through more logic in BUILD? I'm not too familiar and if this seems like an obtuse way of getting what I need, please let me know.

code:
use ESP::DB::Object::Users;

has 'username' => (
    'isa' => 'Str',
    'is'  => 'rw',
);

has 'rose' => (
    'isa' => 'ESP::DB::Object::Users',
    'is'  => 'rw',
    'handles' => [ 'password' ],
);

sub BUILD {
    my $self = shift;

    my $user = ESP::DB::Object::Users->retrieve( user => $self->username );

    $self->rose($user);
}

Fenderbender
Oct 10, 2003

You have the right to remain silent.

atomicstack posted:

You can add delegates at run-time, but you'll have to pay the toll of mutability, and to be honest database schemas don't really change all that frequently. Unless you need to do it that way, you might be best off hacking some meta-code into your toolchain so that when you update your schema files, a complete Moose role will pop out that contains a correct has 'rose' declaration, with the table's column names listed as delegates under handles. Then you can replace your existing has 'rose' declaration with, err, with.

Did just what you described, took all of 5 minutes to do. Clarifies and compartmentalizes the objects properly with little effort. Moose rules. :)

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Say, I'm building an object like so:

code:
    my $events = new ESP::Objects::Events(
        lat   => $lat,
        lng   => $lng,
        range => $range,
    );
and for example, $range is not defined in this context.

Now in the ESP::Objects::Events I have:

code:
has 'range' => ( is => 'rw', default => 10 );
has 'lat' => ( is => 'rw', default => 36.170103 );
has 'lng' => ( is => 'rw', default => -86.770315 );
What would be the proper way to predicate or what-have-you to make it so that if the value passed to these is undef it goes to the default value?

Fenderbender
Oct 10, 2003

You have the right to remain silent.
On that note, how would I go about altering the delagations (handles) for an attribute. My idea is to call the fields method on a Rose::DB::Object subclass and then push that all to a specific attribute's delegations. Haven't been able to figure out how to do this yet but it will solve a lot of upcoming issues I'm going to have to slave over if I don't do this now.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Just going to reask this:

Fenderbender posted:

On that note, how would I go about altering the delagations (handles) for an attribute. My idea is to call the fields method on a Rose::DB::Object subclass and then push that all to a specific attribute's delegations. Haven't been able to figure out how to do this yet but it will solve a lot of upcoming issues I'm going to have to slave over if I don't do this now.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
Hurf durf Windows. :B

Fenderbender
Oct 10, 2003

You have the right to remain silent.

demonbleh posted:

They're vim fold markers.

why not just enable perl_fold in vim? :confused:

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Triple Tech posted:

I recently took up a new job in NYC in one of the city's like... five or so active Perl shops. It's like a vicious cycle! Anyway, I should be back on the Perl grind soon. :) I'm going to miss Visual Studio...

Probably took my last job. ;X

Fenderbender
Oct 10, 2003

You have the right to remain silent.
I think Perl6 itself won't be making any converts in business, but once a web framework project gets to a stable level and a few evangelists and success stories get out there, there will probably be a slow shift to it.

Fenderbender
Oct 10, 2003

You have the right to remain silent.
yeah you should immediately have red flags going off for backticks the same as when you see eval()

Fenderbender fucked around with this message at 21:50 on Jan 8, 2011

Adbot
ADBOT LOVES YOU

Fenderbender
Oct 10, 2003

You have the right to remain silent.

Otto Skorzeny posted:

NB. block eval != string eval

I thought about editing that to make myself more clear, but was too lazy. Thanks for clarifying.

  • Locked thread