Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

List or Scalar?

by hagen (Friar)
on Aug 27, 2003 at 07:08 UTC ( #286956=perlquestion: print w/ replies, xml ) Need Help??
hagen has asked for the wisdom of the Perl Monks concerning the following question:

Learned Monastic Denizens

I've tried everything I know, consulted perlop on Range Operators, checked Perl in a Nutshell (Camel book at home) but this has me puzzled.

I'm trying to calculate the end column of a range of cols in an Excel s/sheet. I know where the range starts, and I know how many more cols I need to `add' to the start to get to the end. Ah hah! I thought, time for the `magic strings' and eventually came up with this snippet to convince me I was on track:-

#!/usr/bin/perl use strict; use warnings; # # test the magic strings # my $col = 'p'; my $limit = 120; for (-5..$limit) { $col++; print "$col,"; }

Success! Works as advertised and I end up with column ref `el'. So I moved the same, so I thought, approach into the real program...

#!/usr/bin/perl use strict; use warnings; use Win32::OLE; use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Excel'; use Win32::OLE::Variant; use Win32::OLE::NLS qw(:LOCALE :DATE); # </readmore> # Based on `Using Win32::OLE and Excel - Tips and Tricks' # by cacharbe - Mar 22, 2002 - node_id=153486.. with thanks 8-) # <readmore> $Win32::OLE::Warn = 3; my ($ex, # this will be the ref to the Excel applicatio +n $book, # ref to the entire workbook $sheet, # a particular worksheet $sheetcount) # count of all sheets in workbook = undef; # Check that Excel is running - if not, start it eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')}; die "Excel not installed" if $@; unless (defined $ex) { # if $ex is undef here, need to sta +rt Excel $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit; +}) or die "Oops, cannot start Excel"; } my $excelfile = "D:/murray/cut_test.xls"; # open existing workbook $book = $ex->Workbooks->Open($excelfile); $sheetcount = $book->Worksheets->Count(); # open an output file to take csv formatted results open CURR, ">", "cut_extract.csv" or die "Can't open Extract for writing $!"; # get the "one-off" key information from the top of the Total Su +mmary sheet $sheet = $book->Worksheets("Total Summary"); my $key_values = $sheet->Range("M1:M8")->{Value}; my ($project, $term, $local, $currency, $segment, $LOB, $first +_month, $owner) = @{$key_values}; for (@$key_values) { print CURR "@$_,"; # values out to .csv a +s expected. } print CURR "\n"; $sheet = $book->Worksheets("FTE"); # get focus on the FTE w +orksheet </readmore> # calculate the end column of months - month -6 starts in col P # so we need $term + 6 cols added to P. The $range for Excel is + specified # as "CR:cr" where CR is the top, left cell of the range, and cr + the bottom # right. # # Determine the right-most column = 'P' + 6 + $term my $col = 'P'; print "\$term is @{$term}\n"; # prints 120 as required for(-5..@{$term}) { # but `..' seems to be in scalar c +ontext! $col++; print "$col,"; } undef $book; undef $ex; close CURR;

But here I only end up with `W'... as if once -5 gets to zero the `..' flip-flops, then @{$term} is TRUE, and the iteration stops.

I'd appreciate some enlightenment in this branch of our theosophy... 8-)

... with humble thanks hagen

Comment on List or Scalar?
Select or Download Code
Re: List or Scalar?
by shenme (Priest) on Aug 27, 2003 at 07:25 UTC
    Ummm, if $term has the right value in it, why did you say
    for( -5..@{$term} ) {
    Why not just
    for( -5..$term ) {
    I think you got carried away with the specialized idiom of how to force values to be interpolated within strings, such as you used in
    print "\$term is @{$term}\n";
    But even here you could have just said
    print "\$term is $term\n";

    The value @{$term} is evaluating to an undefined value, which is somehow getting converted into a value of zero. If I say

    for( -5..undef ) {
    directly I get nasty warnings "Use of uninitialized value in foreach loop entry at line 36." Also if I use a variable with an undef value.

    Why so?

      Thanks shenme... in the actual program the value is in a reference (as returned by the Win32::OLE module) - and is deref'ed (as I understand it) by the @{$term} syntax - it's come from a (ref to an) array of refs.

      What makes me think that this is correct is that the

       print "\$term is @{$term}\n"

      prints the value I want. However when I use the same @{$term} syntax in the range operator it doesn't seem to deref correctly - or I'm making some other sort of mistake.

Re: List or Scalar?
by antirice (Priest) on Aug 27, 2003 at 07:29 UTC

    Data::Dumper is your friend. If your print line is really printing that, then $temp should look as follows when you use print Dumper $temp;

    $VAR1 = [ 120 ];

    If that's the case, then you should be using $temp->[0] instead of @{$temp} as it returns the length of your array (which is 1) in scalar context.

    If this is entirely wrong, the reason I think $temp is an arrayref is because using @{$temp} doesn't result in strict going on how 120 isn't an arrayref at line blah. Also, the OP said he was able to print "\$temp = @{$temp}\n"; and it prints out 120 which would be expected behavior for an arrayref.

    Hope this helps.

    The first rule of Perl club is - use Perl
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: List or Scalar?
by NetWallah (Abbot) on Aug 27, 2003 at 14:20 UTC
    I think this snippet explains your predicament.
    >perl -e "$a=[120]; for (-1..@{$a}){print qq($_\n)}; print qq( \$a=$a \@a=@{$a} value=$a->[0]);" OUTPUT: -1 0 1 $a=ARRAY(0x224f44) @a=120 value=120
    Note that $a is an array ref, and @a in a print context returns the equivalent of join (' ',@a), which is a single element of 120.

    To get your "for" right, you need to use

Re: List or Scalar?
by hagen (Friar) on Aug 27, 2003 at 23:28 UTC

    Many thanks to antirice and NetWallah - their diagnosis is absolutely correct; and I have now a (little) better understanding of Perl's references

    Using the $term->[0] syntax is the answer and I now assume that the print command was kinda "DWIM"ing the ref for me, but in the for loop it wasn't. A bit subtle for my present level of Perlishness 8-)... but on further reflection this would be because print is in list context - and of course the (-1..@{$term}) is scalar - Insight!

    antirice... Data::Dumper printed as follows

    $term is 120 $VAR1 = [ '120' ];

    ... are the single quotes trying to tell me something?

    and NetWallah... Thanks for that very revealing code snippet... I'll keep a copy of that to remind me of the various syntactic options re references. I've just re-read MJD's perlreftut and I think I see where I misunderstood the syntax.

    cheers and thanks again... what a great resource Perl Monks is..... hagen.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://286956]
Approved by weini
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2015-03-03 09:09 GMT
Find Nodes?
    Voting Booth?

    When putting a smiley right before a closing parenthesis, do you:

    Results (66 votes), past polls