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
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

mister_gosh
May 24, 2002

Triple Tech posted:

Two things. One, it sounds like what you're asking for is to output to a file as soon as possible. That is achieved by the following:

code:
$|++;
I'm fully aware that it looks crazy, but that's the way most Perl programmers write it. It sets the output autoflush variable to true. That means every time something gets sent to a filehandle, it will definitely show up. I don't think a handle needs to be closed to be written to this way, that's what I'm banking on.

The other thing is how to clean up a mess when you've been interrupted. You get around that with a signal handler. I believe the Ctrl-C signal is SIGINT. You override that handler with your code and it will be run every time someone interrupts your program. But that's probably not what you want to do here.

Thanks, this is invaluable stuff!

mister_gosh
May 24, 2002

I have a problem with encoding. The resulting file must be UTF-8.

I am opening a file handle, doing something with each line and then printing it out.

code:
open (IN, "C:\\in2.xml") || die("couldn't open C:\\in2.xml for reading\n");
open (OUT, ">C:\\out2.xml") || die("couldn't open file for writing\n");

while(<IN>) {
  my $line = $_;
  chomp($line);

  #Encode::from_to($line, "utf8", "utf8");  # Line 8
  Encode::from_to($line, "iso-8859-1", "utf8"); # Line 9
 
  # OTHER STUFF ...

  print OUT "$line\n";
}
close IN;
close OUT;
Oftentimes, my file is iso-8859-1 so I use the Encode::from_to routine to convert it.

Other times, that makes things worse because it is already in utf8.

Is there a way to test if the line is already utf8? I think I need a good encode tutorial.

mister_gosh
May 24, 2002

What does the extra dollar sign mean in a variable?

For example: $$variableName

mister_gosh
May 24, 2002

How can I NOT store the path for the files I put in a zip archive?

In other words, when you open the zip file, each file has a path of abc/def (see $myDir below). I don't want a user extracting the zip and having it generate the directories abc/def. I just want it to extract to a directory equaling the filename of the zip.

For what it's worth, here's the code-

code:
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
              
my $myDir = "C:/abc/def";
          
my $zip = Archive::Zip->new();
my $zipped;
my @fileList;
find sub { push @fileList, $File::Find::name if basename($File::Find::name) =~ /\.xml/ }, $myDir;

foreach $file (@fileList) {
   $zipped = $zip->addFile( $file );
}
if($zip->writeToFileNamed( "C:/sa.zip" ) != AZ_OK) {
   print "you loving bitch\n";
}
Thanks in advance!

mister_gosh
May 24, 2002

fansipans posted:

Which is funny, because I already had those two URLs open in my browser :psyduck:

Haha, thanks guys!

I saw the new name parameter but dismissed it immediately because I wanted the name to be the same in the zip file (duh!)...I hadn't considered that the filename I was passing in was the full name, it makes sense now.

mister_gosh
May 24, 2002

I have an incredibly basic Perl and IO stuff in general question.

I have a database related app that takes about 4 minutes to run. While it does so, it some known variable values to the screen.

I just ran this same program but told it to not print the messages and it took only 2 minutes. Nothing is different. The same variables are being collected. The only difference is I am not executing the print statements.

What the heck? Does it really take half of the time to print my variables?

I'm not sure how much data is sent to the screen during one submission, but I would guess 2MB at most.

mister_gosh
May 24, 2002

I am retrieving a path from an external source and now have a string:

C:\Program Files\Foo Bar Baz\bin

I need to shorten it like so:

C:\Progra~1\Foo Ba~1\bin

Any idea how I can do this with the least amount of packages?

mister_gosh
May 24, 2002

Triple Tech posted:

GetShortPathName from Win32

Works great, thanks!

mister_gosh
May 24, 2002

I have a long line with thousands of characters. I want to find each occurrence of the string abc(\d+) and do something with it.

For example, I may have:

abc123 blah blah abc456 blah blah abc789 blah

What's the best way to attempt this?

Futile attempt:

code:
while($line =~ m/abc(\d+)/) {
  $line =~ m/abc(\d+)/;
  $thisOne = $1;

  # do something to it
  $line =~ s/abc(\d+)/ABC(\d+)/; # rename so we don't process again

}
This is terrible code. Help!

mister_gosh
May 24, 2002

^^^^ Thanks!!!! vvvv

mister_gosh fucked around with this message at 02:13 on Feb 17, 2009

mister_gosh
May 24, 2002

I'm setting up a bunch of client machines with some custom programs. Most are working except one. I'm getting the error:

code:
Can't locate FooBar.pm in @INC (@INC contains: C:\Acme C:\Perl\LIB 
C:\FooBar C:/Perl/site/lib C:/Perl/lib)
The package FooBar.pm is definitely in C:\FooBar so I'm not getting why it won't find it. It finds it on other client installs.

mister_gosh
May 24, 2002

Wow, so this is how the PERL5LIB was defined:

code:
C:\PERL\LIB;C:\FOOBAR 
                      ^
I put in an extra line with a caret to note where the rogue space was. Really? It doesn't just chop that off?

Thanks guys!

mister_gosh
May 24, 2002

This code is printing, simply "Error: 18":

code:
  my $iError = &foo();
  if ($iError) {
    print "Error: $iError\n";
    exit(1);
  }
  
  sub foo {
   
   my $iError;

   if($^O eq "MSWin32") {
      eval "use Win32::Process";
      my $oProcess;
      Win32::Process::Create($oProcess,$something,'"'.$something.'"
           "'.$somethingElse.'"',0,NORMAL_PRIORITY_CLASS|DETACHED_PROCESS,$dir);
      $iError=Win32::GetLastError();
   }
    return $iError;
  }
What is "18" and is it related to the process it is running (an error code from that?) or is it an error code from the Win32 package itself?

mister_gosh
May 24, 2002

Right but what would "18" be?

I should mention that this used to work fine, but there has been some upgrades of multiple components.

The process I am calling as well as Perl going from 5.8.3 to 5.10.0.

Is it possible that an older version of Win32 is being called? I really doubt this.

mister_gosh
May 24, 2002

Thank you!! I had tried googling but my search was too refined, I think.

Not sure what it means because the process finishes successfully but at least it's better than 18.

mister_gosh
May 24, 2002

It seems that 5.10 (was working fine in 5.8.3) introduced some extra tainting security on looking up environment variables. At least I think that is the problem but I'm not quite clear on how to fix it. Google only mentions the "PATH" variable and it appears they have some hard-coding in the solution, which isn't making sense to me.

This used to work:

my $myVar = $ENV{'MYVAR'}; # typically this would be "D:\mypath\myfile" but it could be anything

Now it is just a blank value.

Edit: its a USER variable, moved it to SYSTEM and it works fine. Not sure what is different now.

mister_gosh fucked around with this message at 21:42 on Jun 11, 2010

mister_gosh
May 24, 2002

Are there any considerations to make with this script on W7? It works fine on my XP machine but does not work in W7 on a particular machine. The permissions appear to be open for the user (I believe they are an admin, in fact):

code:
open(LOG, ">C:/helloworld.txt");
print LOG "hello world";
close LOG;

mister_gosh
May 24, 2002

The Gate of Nanna posted:

What distribution of Perl are you using for Windows? ActiveState? Strawberry?

Try this: (open's 2 vs 3 arg may be different on Windows)
code:
open(my $LOG, '>', 'C:/helloworld.txt') or die $!;
print {$LOG} "hello world";
close $LOG;

It is activestate 5.10.0

I'll have the user try that. Thanks!

mister_gosh
May 24, 2002

How can I print the current package or program name?

Pseudo code:
code:
package abc;

...

print "Name of current package is " . __PACKAGE_NAME__ . "\n";

mister_gosh
May 24, 2002

qntm posted:

That is actually almost it.

Thanks! That makes googling for it easier (left my Perl in a Nutshell book in the wrong location today.

mister_gosh
May 24, 2002

I have a requirement to replace characters in a given string so that it only contains A-Za-z0-9.-_

Can anyone point me in the right direction? Thanks in advance!

code:
$name = "Bill ( $tickers ) i$ innoc3nt!!"; 

while($name contains something other than /A-Za-z0-9\._\-/) {
    $name =~ s/BAD_CHARACTER/\-/;			
}

print "$name\n";
Bill----tickers---i--innoc3nt--

mister_gosh
May 24, 2002

Wow, thank you. I thought it was going to be much more complicated (substrings, looping, etc.). I switch between too many languages (the worst, of which, is XSLT).

Thanks!

Adbot
ADBOT LOVES YOU

mister_gosh
May 24, 2002

Is there a case-sensitive method to test for file existence?

For example, if I have a file named C:/Abc.txt, then I want "it does not exist" to print:

code:
$file = "C:/abc.txt";
if(-e $file) {
   print "it exists";
} else {
   print "it does not exist";
}

  • Locked thread