Re: Win32 Environment Variable Read-only?
Using AS Perl 5.8.7 under W98SE, the PATH environment variable is displayed, then assigned a new value; but the new value doesn't propagate back to the MS-DOS %PATH% variable. Are the %ENV values read-only? Many thanks to Robert, Bill, Alex, and Chris who responded to this inquiry. I should have figured out that child processes can't change their parent environment (but didn't)... and thus the value of this community. The original problem was that, after startup, the PATH contains duplicate pathnames. After debugging the startup sequence (IO.SYS-MSDOS.SYS-COMMAND.COM-CONFIG.SYS-AUTOEXEC.BAT), the problem seemed to originate with IO.SYS, which is a hard module to modify. So I wrote a PERL program that culled duplicates from the PATH environment variable and assigned the new path string to $ENV{PATH}. I tried to interpret it from AUTOEXEC.BAT, but got a Not a DOS program (probably in real mode) error message at boot time. I then tried to execute it from the shortcuts for the command prompts, but for the reason stated, that didn't work. The less-than-desirable fix that I'm now using is to reference batch-file SHELLINI.BAT in the shortcuts to the command-prompts. The batch-file invokes the PERL interpreter as in: ... Perl C:\Programs\Scripts\PATHcull.plx CALL C:\PROGRAMS\Scripts\PATH.BAT ... PATHcull.plx splits the PATH string into pathnames, culls out the duplicates, and concatenates a new string ($sRed), which is written in a SET PATH=$sRed command to file PATH.BAT (yes, the Admin's hack -- the temporary batch-file -- rears its hoary head). And SHELLINI.BAT calls PATH.BAT to execute the SET PATH command. At least that fixes PATH for each instance of the command-prompt. Regards, Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Win32 Environment Variable Read-only?
Using AS Perl 5.8.7 under W98SE, the PATH environment variable is displayed, then assigned a new value; but the new value doesn't propagate back to the MS-DOS %PATH% variable. Are the %ENV values read-only? C:\Programs\PERLSET ... PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\PERL\BIN\;C:\THINKPAD ... C:\Programs\PERLperl print $ENV{PATH}\n; $ENV{PATH} = 'C:\WINDOWS;C:\WINDOWS\COMMAND'; print $ENV{PATH}\n; ^D C:\WINDOWS;C:\WINDOWS\COMMAND;C:\PERL\BIN\;C:\THINKPAD C:\WINDOWS;C:\WINDOWS\COMMAND C:\Programs\PERLSET ... PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\PERL\BIN\;C:\THINKPAD ... ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Importing Identifiers from Main::
On Thursday, June 30, 2005 1:25 AM, $Bill Luebkert [SMTP:[EMAIL PROTECTED] wrote: You could start that package off with a 'package main;' stmt which will put you in the same namespace as the calling module. Good idea. This obviates the need to import identifiers. Rob suggested a similar approach yesterday. You can use an array's scalar context to make this easier to read : for (my $i = 0; $i @{$rT}; $i++) { Thanks for the coding critique. You're right. Any idea if either form evaluates faster? $#array or scalar @array? # using constants (but you have to export them to the other module like your glob refs): use constant xbi = 0;# index into data arrays, begin time use constant xei = 1;# index into data arrays, end time use constant xi = 2;# indicator use constant xs = 3;# signal use constant xa = 4;# amplitude use constant xt = 5;# elapsed time use constant xr = 6;# trend I prefer this approach, notwithstanding the need to copy the definitions into the module(s) that use them: 1) The indices really are constants, and the pragma makes that clear. 2) Dropping the $ from the symbol in the anonymous array index makes it clear when reading the body of the code that the index isn't going to change (I probably would use all caps in the identifiers to emphasize this). 3) The identifiers are shorter by one character. 4) If the compiler in-lines the constant (or subroutine that coughs up the constant), it may execute faster. # using a hash: my %IX = ( xbi = 0; # index into data arrays, begin time xei = 1; # index into data arrays, end time xi = 2;# indicator xs = 3;# signal xa = 4;# amplitude xt = 5;# elapsed time xr = 6;# trend }; This is also a good idea in that the identifiers are passed with the array, and there's no need to define them in each module. However, Johanes Lindstrom's method of using anonymous hashes appeals to me because it's so natural to read. Bill, I really appreciate your commentary on the code and the expert suggestions you have made -- as usual. -Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Importing Identifiers from Main::
On Thursday, June 30, 2005 09:33:23 +0200, Johan Lindstrom [SMTP:[EMAIL PROTECTED] wrote: This is what I meant when I said a hash is a good solution to this problem. You're not really interested in the order, you want to access each element by a convenient name. It sounds like a bit of data to keep in memory, so going from an array to a hash may not be feasible because of that, but if it is it would look like this instead: $trade[$i]-{time_elapsed} If your available memory can take this hit, I'd consider that approach a lot more maintainable. If not, go with either exported constants or simply $UPPER_CASE_VARIABLES as named indices into the array. I didn't mean to ignore this approach. I really like it because: 1) The symbols are contained in the hash and don't have to be imported. And, 2) It's self-documenting (presume this is what you meant by maintainable) -- very easy to read. The memory may not support this design for this particular array, but I will use it on one, maybe two, smaller arrays. Thank you very much. And to me it looks like the solution would be more clear with each record being an object, but if you're not familiar with OO, don't start introducing it in this program. Try it out with something small and new. http://www.manning.com/books/conway is excellent. Thanks for the reference. I remember Conway as the author of Switch.pm. Should be good. I appreciate the investment of time and quality of your suggestions. --Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Importing Identifiers from Main::
On Wednesday, June 29, 2005 2:19 AM, $Bill Luebkert [SMTP:[EMAIL PROTECTED] wrote: Your explanation leaves a little to be desired. You could knock it down to a single hash that contains pointers to all your arrays if that helps. Then you could use names instead of numbers (or not). Not sure it's appropriate or not without seeing some access code. Thank you for responding. Sorry about the ambiguity. The main program is a sequence of computational processes that reads several files of 20K to 50K records and splits them into 12 parallel arrays of that length. Analytic routines generate an array (@trade) of 2K to 4K elements, each of which is a reference to an anonymous array of, say, 7 elements; built like so: for ($iS=1; $iS=$#sigs; $iS++) { ... # processing... push(@trade,[$j,$i,TaS,$sig,$amp,$elT,$tre[$j]]); # append trade to array }#for [0]begIx,[1]endIx,[2]indic,[3]type,[4]amplitude,[5]elapsedTime,[6]trend Further on, other processes access this data for analysis, and to build and print other arrays, like so: for ($i=1;$i=$#trade;$i++) { ... # processing... push (@tCycle, [$j,$l,$m,$trade[$i]-[2],$phWin,$trade[$i-2+$sSC]-[4], $trade[$i]-[5]+$trade[$i-1]-[5],[EMAIL PROTECTED]); ... # processing... }#for A module was designed (TSP.pm), which contains two subroutines, one which prints descriptive statistics, and one which prints performance metrics for the @trade data. The subroutines, in general, access individual elements of the anonymous arrays, like so: for ($i=0;$i=$#{$rT};$i++) { ... # processing... $da = int(${$rD}[${$rT}[$i]-[0]]/86400)*86400; # $rT is ref to @trade ... # processing... }#for As mentioned previously, I got tired of editing the absolute indices (e.g., $trade[$i]-[6]) every time the order or meaning of an element of the anonymous arrays changed; so in main I defined typeglobs: *xbi = \0;# index into data arrays, begin time *xei = \1;# index into data arrays, end time *xi = \2;# indicator *xs = \3;# signal *xa = \4;# amplitude *xt = \5;# elapsed time *xr = \6;# trend ...to allow the use of variables for the indices, like so: push (@tCycle, [$j,$l,$m,$trade[$i]-[$xi],$phWin,$trade[$i-2+$sSC]-[$xa], $trade[$i]-[$xt]+$trade[$i-1]-[$xt],[EMAIL PROTECTED]); My question is how best to get those typeglobs into the namespace of module TSP.pm so that, when I make a change, it's once in main, and the change is automatically propagated into TSP.pm. Right now, I just cut and paste the typeglobs from main into TSP.pm. Thank you. -Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Importing Identifiers from Main::
Thank you for responding. Please see my detailed explanation, posted to Bill Luebkert recently. On Wednesday, June 29, 2005 10:42:45 +0200, Johan Lindstrom [SMTP:[EMAIL PROTECTED] wrote: If you're familiar with OO, that sounds like the way to go. You have data. You have subs that act on this data. That's a class right there. I am not conversant with OO, although this approach sounds interesting. Create a new module for the constants. perldoc Exporter or http://search.cpan.org/~nwclark/perl-5.8.7/lib/Exporter.pm http://search.cpan.org/~nwclark/perl-5.8.7/lib/Exporter.pm#How_to_Export http://search.cpan.org/~nwclark/perl-5.8.7/lib/Exporter.pm#How_to_Import This is a good suggestion. I have two reservations: 1) Containment of the number of modules. 2) Good practice would define the constants used as indices in the same namespace as the array that uses those indices (main), not in another module. However, I keep having the same experience with Modula-2 -- end up creating a separate module with constants/structures/etc. common to the other compilation units and have all the other modules import it. Thanks for the references. I may go this direction. --Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
RE: Importing Identifiers from Main::
On Wednesday, June 29, 2005 3:10 AM, Sisyphus [SMTP:[EMAIL PROTECTED] wrote: Perl in a Nutshell is quite correct here, I think. If the module does not have a package name (which is rarely the case) then $var, $::var, and $main::var are all the same thing. D:\pscrpttype trial.pm sub double_it { return $var * 2} 1; D:\pscrpttype try.pl use warnings; use trial; $var = 17; $var++; $z = double_it(); print $z, \n; D:\pscrptperl try.pl 36 D:\pscrpt I think it's only if trial.pm had a package name (as it normally would) that 'double_it' would have to be coded as either: sub double_it { return $::var * 2} or: sub double_it { return $main::var * 2} Rob, you get credit for a neat example and for an easy solution that may fit (obvious to you, but I never considered it)-- extend main's namespace over several files. The reason $var is recognized in double_it() is that trial.pm is still in main's namespace when trial.pm's subroutine is compiled. This means that use trial in try.pl just looked in the current directory, found a file called trial.pm, assumed it was a module, and went forward with the compilation, not caring whether trial.pm had a package declaration or not. There was nothing to import since trial.pm didn't export anything. But, according to Nutshell, trial.pm isn't a module. Note what Nutshell says under Modules (p. 160): A module is a package defined in a file whose name is the same as the package. Now note what Nutshell says about packages under Namespaces and Packages (p. 160): Each package starts with a package declaration. The package call takes one argument, the name of the package... So, according to Nutshell, a module must start with a package declaration that includes the name of the package. (Therefore Nutshell still has a problem: $var isn't the same as $::var and $main::var if the symbol table changes due to a package declaration, which must be present according to their definition.) Your reference to #define statements and constants makes me wonder whether you might want to make use of the constant pragma (see perldoc constant), but since I can't quite get a picture of the precise scenario, I can't be sure :-) I'll look at this very carefully, not just for this case, but for similar situations. Maybe your question is perfectly clear to someone else . otherwise you might have to provide a simple little demo module and script to illustrate the problem. In fact my explanation wasn't clear to anyone, and I apologize. Please see my recent response to Bill Luebkert for a detailed elucidation. Your comments have been very helpful, and I am very appreciative. Regards, Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Importing Identifiers from Main::
Problem Statement: The main program creates an array of pointers to anonymous arrays, each of which has about 10 elements. Since I am in the development phase, I keep changing the order and identity of the elements. Because there are many lines of code that reference those elements, I abandoned numeric offsets (indices) and went to variable offsets (actually I use typeglob refs to constants to catch instances where I might accidentally try to change one). I also coded a module with subroutines that manipulate this array, so I'd like to define the offsets in main:: and simply have their symbols and values trickle down into the module's (package) symbol table. I was initially misled by PERL in a Nutshell which says, under Namespaces and Packages, If the package name is null, the main package is assumed. For example, $var and $::var are the same as $main::var (p. 160). After more reading and testing, it was determined that $var really _must_ be qualified as $::var to be seen in the module. Since the qualifier expands these short variable names, and some of the lines of code are long as is, I turned away from qualified names. Right now, whenever the definitions change in main::, I simply cut and paste them into the module, and all works well. But there are four more big data arrays that are in development, and I'm tired of cutting and pasting. (I keep thinking about C header files and #define statements...) Question: What's the best way to handle this situation? Can I export those offsets from main:: and use them in the module? Or is there some pragma that can be used to generate compile-time constants with global visibility? Any suggestion would be appreciated. --Neil ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
Can't use $\ to force line termination to 0x0a
An MS-DOS batch file launches a PERL script which calculates input specifications for a filter-design program written in FORTRAN running under cygwin's shell for MS-DOS. The specifications are written by PERL to many text-files which are read by the UNIX-based program. Therein lies the problem. PERL for Win32 writes the line terminators as CRLF (0x0d0a), and the UNIX-based program blows up reading the unexpected character CR. What we want to do is write LF (0x0a) as the text-file termination character. Simple, no? PerFunc documentation for binmode() says: See the $/ and $\ variables in the perlvar manpage for how to manually set your input and output line-termination sequences. The PerlVar documentation for $\ says: Ordinarily the print operator simply prints out its arguments as is, with no trailing newline or other end-of-record string added. To get behavior more like awk, set this variable as you would set awk's ORS variable to specify what is printed at the end of the print. (Mnemonic: you set $\ instead of adding ``\n'' at the end of the print... So we did what it what it said (I hope). LineTermTest.plx tests different combinations of $\ and \n. No configuration produces the desired LF termination. # 'print' Line Termination Test # Use od -Ad -txz fname to display hex dump of output # 1. What is the default setting of $\? # ($\ is a scalar that contains a string.) $BS = $\; if (defined ($BS)) {print ($BS)} # Can't use $\ before double-quote else {print \$\\ undefined on entry.\n} # Output: $\ undefined on entry. # 2. String with default $\ but no \n print (A); # Output: 0x41 [no termination] # 3. String with default $\ and \n print (B\n); # Output: 0x420d0a [B followed by CRLF] # 4. String with $\=\x0a, no \n # Backslash escape to insert hex value in double-quoted string $\ = \x0a; print (C); # Output: 0x430d0a [C followed by CRLF] # 5. String with $\=\x0a and \n print (D\n); # Output: 0x440d0a [D followed by CRLF] # 6. String with embedded LF, no \n print (E\x0a); # Output: 0x450d0a [E followed by CRLF] Is $\ being overridden? It appears that even though $\=\x0a may terminate print lines with LF, this character is replaced by CRLF at a lower layer before output to the file. Does $\ work as advertised under W32? Sorry for using the -v option :-) Thank you, Neil Environment: W98SE, ActiveState PERL for MSWin32-x86-multi-thread, build 631, 1/2/2002. ___ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs