[31462] in Perl-Users-Digest
Perl-Users Digest, Issue: 2714 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Thu Dec 10 18:09:41 2009
Date: Thu, 10 Dec 2009 15:09:09 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Thu, 10 Dec 2009 Volume: 11 Number: 2714
Today's topics:
Re: Any way to tell if a scalar is a string? <uri@StemSystems.com>
Re: Any way to tell if a scalar is a string? <jl_post@hotmail.com>
Re: Any way to tell if a scalar is a string? <uri@StemSystems.com>
Re: Any way to tell if a scalar is a string? <jl_post@hotmail.com>
Re: Any way to tell if a scalar is a string? <jl_post@hotmail.com>
Re: Any way to tell if a scalar is a string? <ben@morrow.me.uk>
Re: foreach - sorted array the way I want? <tadmc@seesig.invalid>
Re: How big do your programs get before you modularise <rburbrid@cisco.com>
Re: How big do your programs get before you modularise <john@castleamber.com>
Re: How big do your programs get before you modularise <ben@morrow.me.uk>
Re: How big do your programs get before you modularise <jurgenex@hotmail.com>
Re: i18n - and 2-headed strings? <ben@morrow.me.uk>
Re: Trying to avoid passing params to subs through glob (Randal L. Schwartz)
Re: Trying to avoid passing params to subs through glob <ben@morrow.me.uk>
Re: Trying to avoid passing params to subs through glob <tadmc@seesig.invalid>
Re: Unblessed reference. <rburbrid@cisco.com>
Re: Unblessed reference. sln@netherlands.com
Re: Unblessed reference. <rburbrid@cisco.com>
Re: Unblessed reference. <ben@morrow.me.uk>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Thu, 10 Dec 2009 14:38:22 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <874onysjpt.fsf@quad.sysarch.com>
>>>>> "jpc" == jl post@hotmail com <jl_post@hotmail.com> writes:
jpc> On Dec 9, 6:26 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
>> a scalar value can be both an integer and string
>> at the same time. so dumper could report one
>> or the other based on how it looks at things.
jpc> That's very true. It's just that sometimes I extract text with
jpc> unpack() that is all numbers, but represents a name or identifier,
jpc> rather than a quantity (examples are "286", "386", and "486" Intel
jpc> architectures).
jpc> In such a case, if I extract it as a string, I want to report it as
jpc> text (even though I could technically report it as a numerical
jpc> value). So if Data::Dumper reports it as a string, chances are I also
jpc> want to report it as a string, as well.
jpc> True, Perl seamlessly converts strings that look like numbers to
jpc> numbers and vice-versa (which is very convenient in most cases), but
jpc> in this case I'd to know that such a value was extracted from text.
but all you have is text to start with. all of your values would be text
in that context. you need to apply some parsing or heuristics to know
what should stay as text or be converted to a number. but as i keep
saying, i think you are barking up the wrong tree. a proper parser would
do better for you than unpack and then you would always know the
context and what a value should be. unpack is used when you have a known
fixed format but you don't have that.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Thu, 10 Dec 2009 12:09:16 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <12fe2263-d51a-4faf-8cff-82dcc30054e5@z4g2000prh.googlegroups.com>
> jl post@hotmail com <jl_p...@hotmail.com> writes:
>> That's very true. =A0It's just that sometimes I extract text with
>> unpack() that is all numbers, but represents a name or identifier,
>> rather than a quantity (examples are "286", "386", and "486" Intel
>> architectures).
On Dec 10, 12:38 pm, "Uri Guttman" <u...@StemSystems.com> replied:
> but all you have is text to start with.
Actually, no. I have a mix of text and numerical values to deal with,
as I'm dealing with packstrings similar to 'c x a2' and 'I/i I/(a10) I/
i'. (If that weren't true, I wouldn't have my issue.)
With either packstring I'd get back a mix of numbers and strings. And
I'd like to know which elements were returned as strings, even if they
happen to look_like_numbers().
(But you're right in that if all I had to deal with is text, then
there'd be no need to keep track of what's text and what's not.)
-- Jean-Luc
------------------------------
Date: Thu, 10 Dec 2009 15:19:19 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <87k4wur394.fsf@quad.sysarch.com>
>>>>> "jpc" == jl post@hotmail com <jl_post@hotmail.com> writes:
>> jl post@hotmail com <jl_p...@hotmail.com> writes:
>>> That's very true. It's just that sometimes I extract text with
>>> unpack() that is all numbers, but represents a name or identifier,
>>> rather than a quantity (examples are "286", "386", and "486" Intel
>>> architectures).
jpc> On Dec 10, 12:38 pm, "Uri Guttman" <u...@StemSystems.com> replied:
>> but all you have is text to start with.
jpc> Actually, no. I have a mix of text and numerical values to deal with,
jpc> as I'm dealing with packstrings similar to 'c x a2' and 'I/i I/(a10) I/
jpc> i'. (If that weren't true, I wouldn't have my issue.)
so your pack string knows the format, then you can use it to tell you
what is a number or a string. in either case you have the info and don't
need to determine the data type after the unpacking.
jpc> With either packstring I'd get back a mix of numbers and strings.
jpc> And I'd like to know which elements were returned as strings,
jpc> even if they happen to look_like_numbers().
but you know that. who is creating these pack format strings? if you
are, just break them on spaces (ignored in pack as you seem to know) and
you can easily parse those for number/text.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
------------------------------
Date: Thu, 10 Dec 2009 12:37:57 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <e686b80a-706d-4b90-a6b1-565db84c7324@z35g2000prh.googlegroups.com>
On Dec 9, 5:52 pm, Ben Morrow <b...@morrow.me.uk> wrote:
>
> if (B::svref_2object(\$_)->POK) {
>
> See, I told you you needed to know about perl's guts :).
Point taken! :)
Okay, so to make sure you and I are on the same page, I'd write my
sample script like this:
#!/usr/bin/perl
use strict;
use warnings;
foreach ("7777", 7777, 'foobar', 123_456)
{
use B;
if (B::svref_2object(\$_)->POK) {
print "String\n";
} else {
print "Not a string\n";
}
}
__END__
which outputs:
String
Not a string
String
Not a string
> You should be aware that trying to determine if a
> scalar is a string or a number (other than by using
> looks_like_number) is a highly dubious proposition.
> Perl just isn't set up to consistently record that
> information.
Yes, I've already noticed. I discovered that if I insert the line:
$_ . '';
as the first line of the foreach loop in the above sample script, then
all the elements are reported as strings. On the other hand, if I
make the first line of the loop to be:
$_ + 0;
then the elements still retain their string/non-string property (even
the string "7777", which does not generate a warning when added to 0).
So what I'm taking from this is that Perl internally may (or may
not) change how a scalar is viewed simply by applying it in a
particular context. (In other words, modification is not required for
Perl to see a scalar "differently.")
> If this is just for display, and if you treat the PV form
> as canonical where it exists, you should be OK; but don't
> get the idea this is something you should be doing in general.
This need of mine has only ever come up when I'm writing a utility
script to peek inside binary files (created by programs written in a
language other than Perl). Perl's unpack() function provides a
(relatively) simple way for me to see all the binary file's data at-a-
glance without having to stare at (and navigate my way through) pages
and pages of hex dump output.
In fact, I often use unpack() when I'm trying to track down a bug
concerning corrupted data. The data could be stored to file wrong, or
it could be being retrieved incorrectly. In either case, being able
to look at the file quickly and easily (to locate possible corruption)
is something that's invaluable for debugging purposes, and is exactly
what Perl and its unpack() function afford me.
I've had people tell me that you can't use Perl to look through
binary files created in C/C++ (as if a hex editor or another C/C++
program is required to read/edit the binary file). Those same people
usually react incredulously when I tell them I've already written a
Perl script to do so.
Anyway, thanks a million times over for all your help, Ben.
-- Jean-Luc
------------------------------
Date: Thu, 10 Dec 2009 12:55:19 -0800 (PST)
From: "jl_post@hotmail.com" <jl_post@hotmail.com>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <7a06b5f4-5b23-463f-be09-036c2acb4bfd@b36g2000prf.googlegroups.com>
On Dec 10, 1:19 pm, "Uri Guttman" <u...@StemSystems.com> wrote:
> so your pack string knows the format, then you can
> use it to tell you what is a number or a string.
> in either case you have the info and don't need
> to determine the data type after the unpacking.
I have to disagree. I've worked with packstrings similar to:
'I/i I/(a10) I/i'
and, as I've mentioned in an earlier post, there's no way for me to
necessarily know where the first set (of integers) ends and the second
set (of text) begins and ends, especially if all the text strings in
the second set all happen to look like integers.
> who is creating these pack format strings? if you are,
> just break them on spaces (ignored in pack as you seem to
> know) and you can easily parse those for number/text.
I create the packstrings myself (usually from reading the logic inside
of another language's raw code), but oftimes I end up using dozens of
terms in my packstrings, many of which resemble something like this:
"(i dd a10)5". In such cases, parsing the packstring to figure out if
a specific element was extracted as a string can get very messy very
quickly.
So if Perl knows right off the bat if a scalar was returned as a
string, I'd like to take advantage of that. And it looks like Ben
Morrow's solution to use:
use B;
if (B::svref_2object(\$_)->POK)
accomplishes just that.
-- Jean-Luc
------------------------------
Date: Thu, 10 Dec 2009 21:18:48 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Any way to tell if a scalar is a string?
Message-Id: <o658v6-up32.ln1@osiris.mauzo.dyndns.org>
Quoth Sir Robert Burbridge <rburbrid@cisco.com>:
> On 12/09/2009 07:52 PM, Ben Morrow wrote:
>
> > Don't ever check for class membership with 'ref'. In fact, most uses of
> > 'ref' except as a boolean are bugs. The correct way to check for class
> > membership is to call the ->isa method; if you aren't sure something is
> > an object, you can use Scalar::Util::blessed or wrap it in an eval {}.
>
> Out of curiosity, why "Don't ever check for class membership with
> 'ref'"? Do you mean, "... unless you want to exclude subclassed
> objects", or is there some more dire problem with it that I don't see...
Consider
ref bless [], "HASH";
ref bless [], "0";
for why one of reftype or blessed from Scalar::Util is better, depending
on what you meant. As for exclusing subclassed objects, that is nearly
always a bad idea. The whole point of OO is Liskov substitutability --
that you can *always* use an object of a subclass as though it were an
object of the superclass -- so restricting your check to 'no subclasses'
is nearly always unnecessarily limiting.
Ben
------------------------------
Date: Thu, 10 Dec 2009 14:59:22 -0600
From: Tad McClellan <tadmc@seesig.invalid>
Subject: Re: foreach - sorted array the way I want?
Message-Id: <slrnhi2o35.dsm.tadmc@tadbox.sbcglobal.net>
Tomasz Chmielewski <mangoo@nospam.wpkg.org> wrote:
> I have a script which reads the config file and builds the commands
> which need to be executed.
>
> It pushes each command to an array.
>
> When everything is read from the config file, it is executed like this:
>
>
> foreach my $exec_command (@exec_commands) {
> execute($exec_command);
> }
>
>
> However, such approach does not guarantee that the commands will be
> executed in a proper order.
>
>
> Supposing I would like to have the guarantee that the commands
> containing "someword" will be executed before commands containing
> "someotherword" (and this, before "xyz" command), what would be the best
> approach here?
Make a hash that defines the desired order, write a Schwartzian Transform
that plucks out one of those hash values (I use a "hash slice" below),
compare the hash values as numbers.
-----------------------------
#!/usr/bin/perl
use warnings;
use strict;
my @exec_commands = qw(
an_xyz
someotherword
someword
xyz
more_someword
someotherword_more
more_someotherword
xyz_more
someword_more
);
my %order = (
someword => 1,
someotherword => 2,
xyz => 3,
);
my $keys = join '|', reverse sort keys %order;
my @sorted = map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, @order{/($keys)/} ] } @exec_commands;
foreach my $exec_command (@sorted) {
print "$exec_command\n";
}
-----------------------------
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
------------------------------
Date: Thu, 10 Dec 2009 14:24:53 -0500
From: Sir Robert Burbridge <rburbrid@cisco.com>
Subject: Re: How big do your programs get before you modularise most of it?
Message-Id: <1260473069.780878@sj-nntpcache-2.cisco.com>
On 12/10/2009 08:02 AM, Justin C wrote:
> I keep writing programs that (for me at least) start getting large. I
> know they're small, even by the standard of many of the modules that
> I've seen, but how do you decide when to break down your code and
> modularise?
>
> Do you only create modules if you think the code is likely to re
> re-used, and if it's not then if the program has 10k lines then so
> be it?
>
> I fine myself bashing away at the keyboard, and the next thing I know is
> that I've got 1000 lines and keeping track of what's where starts
> getting complicated (I do love an editor that can fold!). I was just
> wondering how others program.
>
> Justin.
>
I package my modules within the executable when it makes sense for
certain functionality to be grouped. For example, if I find that I've
written code like this:
foo.pl
#!/usr/bin/perl
use strict;
sub handle_script_args { ... }
sub do_something { ... }
sub parse_link { ... }
sub render_link { ... }
sub reformat_link { ... }
sub remove_link { ... }
...
__END__
I'll often do a quickie refactoring to something more like:
foo.pl
#!/usr/bin/perl
use strict;
sub handle_script_args { ... }
sub do_something { ... }
### Woops! Looks like I need to package this up...
package Link;
sub parse { ... }
sub render { ... }
sub reformat { ... }
sub remove { ... }
...
__END__
That makes packaging it pretty trivial when it grows past that.
Sometimes putting a couple minutes of thought into it first shows me
that it should *start out* modularized. In that case I still usually do
it all in the same file, until it's time to break it out. So sometimes
I'll have a 100 line script that has a package or two in it ... maybe
they never grow to need it, but it doesn't *hurt* to do it... =)
-Sir
------------------------------
Date: Thu, 10 Dec 2009 16:29:37 -0600
From: John Bokma <john@castleamber.com>
Subject: Re: How big do your programs get before you modularise most of it?
Message-Id: <874onyo432.fsf@castleamber.com>
Sir Robert Burbridge <rburbrid@cisco.com> writes:
> That makes packaging it pretty trivial when it grows past
> that. Sometimes putting a couple minutes of thought into it first
> shows me that it should *start out* modularized. In that case I still
> usually do it all in the same file, until it's time to break it out.
Same here :-)
--
John Bokma
Read my blog: http://johnbokma.com/
Hire me (Perl/Python): http://castleamber.com/
------------------------------
Date: Thu, 10 Dec 2009 22:33:44 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: How big do your programs get before you modularise most of it?
Message-Id: <8j98v6-nb42.ln1@osiris.mauzo.dyndns.org>
Quoth ccc31807 <cartercc@gmail.com>:
>
> I haven't written any OO Perl, but I have written Java, and I find the
> Java development style completely different. With Java, I will
> decompose the requirements into classes, write the test cases for each
> of the classes, and then write the classes. When the classes behave as
> they ought, I'll write the main application. In essence, this turns
> the development process I use with Perl on its head.
You can do this with Perl as well, of course, and with function-based
modules just as well as with OO modules. The key is to separate out
pieces of your problem that can be solved (and tested) as individual,
well-defined problems on their own.
> Interestingly, I've been playing with Lisp for several years, and find
> myself writing Lisp a couple of hours a day now. The typical
> development style in Lisp is writing and testing the functions that
> you use to compose larger structures. The OO development in Lisp also
> follows a similar pattern. Since Lisp developers use an interactive
> development environment, this style becomes natural and the programs
> 'grow' more or less in an ad hoc manner (which causes neurotic
> reactions in software engineers). Perl 6 supposedly has an interactive
> development environment as well, and I'll bet that the Perl community
> as a whole will gravitate toward this and away from the typical C
> style of designing and developing a program.
I don't know what you mean by 'Perl 6 has an interactive development
environment'. If you mean something Smalltalkish, then AFAIK it doesn't.
If you just mean a REPL, then there are several for Perl 5 on CPAN (and
of course there's always 'perl -de1'), but I don't see how this helps
you break complicated problems down into smaller ones.
Ben
------------------------------
Date: Thu, 10 Dec 2009 15:05:10 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: How big do your programs get before you modularise most of it?
Message-Id: <ggu2i5l620fu1jn5datq03692atmmsa9up@4ax.com>
Justin C <justin.0911@purestblue.com> wrote:
>I keep writing programs that (for me at least) start getting large. I
>know they're small, even by the standard of many of the modules that
>I've seen, but how do you decide when to break down your code and
>modularise?
>
>Do you only create modules if you think the code is likely to re
>re-used,
No
>and if it's not then if the program has 10k lines then so
>be it?
And no.
>I fine myself bashing away at the keyboard, and the next thing I know is
>that I've got 1000 lines and keeping track of what's where starts
>getting complicated (I do love an editor that can fold!). I was just
>wondering how others program.
That's called spagetthi programming and it is very poor style.
The size of a proram has pretty much nothing to do with modules.
The purpose of a module is not to reduce the physical size of a program.
Having a module "Lines5000to10000" obviously doesn't make any sense.
Instead a module encapsulates and abstracts something, e.g. a data
structure or a set of similar functions or something along that line.
Example: I know that my program will use balanced trees. So I create a
module to manage balanced trees and it will contain the typical
functions on such data structures like create item, add element, delete
element, traverse data structure (map or apply-all), and so on.
Same for let's say geometry. If I write a progam that heavily relies on
geometric functions then I create a module to contain all those
functions for surface area of a cylinder and sphere, volume of a cone
and cube and circumference of a triangle,
Neither has anything at all to do with the size of the program.
Now, there is one exception: if the main program grows beyond a certain
size, then I go back and seriously question the basic design. Usually it
turns out that I made a mistake in the very early design stages and
forgot an abstration layer or two and therefore the program grew beyond
being managable.
Cure: go back to square two and add those abstraction layers, of course
each encapsulated in a module, and the program will shrink back to a
more sane size.
jue
------------------------------
Date: Thu, 10 Dec 2009 22:41:32 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: i18n - and 2-headed strings?
Message-Id: <s1a8v6-nb42.ln1@osiris.mauzo.dyndns.org>
Quoth Ilya Zakharevich <nospam-abuse@ilyaz.org>:
> On 2009-12-03, Ben Morrow <ben@morrow.me.uk> wrote:
> > That is for module authors to use to internationalise their modules. It
> > doesn't help with the messages perl generates itself.
>
> Thinking about it more:
>
> A) I find the argument that Perl is a "lingua franca of science and
> technology" very misplaced. *A Perl application* may be designed
> for use by children and/or music lovers.
Um, yes? Who are you arguing with? :)
> B) We need something which works as English during parsing, but is
> printed out in Bengali. This looks like overloading.
>
> Unfortunately, when I designed overloading, I did not think *at
> all* about overloading objects with string semantic. There was
> no provision to treat REx matching specially during overloading,
There is now. I submitted a patch to add 'qr' overloading to 5.12, which
is called when an overloaded object is used on the RHS of =~ or is
interpolated into a regex. Since 5.12 has true REGEX SVs, it seemed
silly not to have a corresponding 'type-cast' overload.
> Basically, what I think of is making $@ into a 2-headed beast, with 2
> different STRING values. What do people think?
There was some discussion of this issue on p5p a while ago, though that
was before qr-overload was different from string-overload. IIRC the
general feeling was that trying to get people to move away from
string-matching $@ by defining a set of numeric error codes for the core
perl errors was probably the best way forward. I don't think any firm
decisions were reached, though, and the question hasn't been revisited
recently.
Ben
------------------------------
Date: Thu, 10 Dec 2009 11:17:27 -0800
From: merlyn@stonehenge.com (Randal L. Schwartz)
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <868wda63lk.fsf@blue.stonehenge.com>
>>>>> "Justin" == Justin C <justin.0911@purestblue.com> writes:
Justin> Further to me recent problem of unblessed references, I'm re-writing my
Justin> code, putting more of it into subroutines so that the main thread is
Justin> more obvious. I'm finding that where I was using global variables there
Justin> appear to be a lot of variables that need passing to some sub-routines.
Sounds like related state correlated with related behavior.
That's called an "object".
Might wanna look into that. :)
If you need, I can recommend a good book (or two :).
print "Just another Perl hacker,"; # the original
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
------------------------------
Date: Thu, 10 Dec 2009 22:15:59 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <vh88v6-nb42.ln1@osiris.mauzo.dyndns.org>
Quoth Justin C <justin.0911@purestblue.com>:
>
> Further to me recent problem of unblessed references, I'm re-writing my
> code, putting more of it into subroutines so that the main thread is
> more obvious. I'm finding that where I was using global variables there
> appear to be a lot of variables that need passing to some sub-routines.
>
> I'm thinking of creating a few hashes of references to these variables,
> and then passing the whole hash (or a reference to it) to the
> subroutine.
>
> my %excel = (
> "worksheet" => \$ws,
> "workboot" => \$wb,
> "format_1" => \$format_1,
> "format_2" => \$format_2,
> );
As Tad said, at this point the extra variables aren't doing anything for
you. Just use the hash entries, so instead of
my $ws;
create_worksheet();
populate_worksheet();
sub create_worksheet {
# this is just an example, of course
$ws = Worksheet->new;
}
sub populate_worksheet {
$ws->add_cell("A1", "foo");
}
you might have
my %excel;
create_worksheet(\%excel);
populate_worksheet(\%excel);
sub create_worksheet {
my ($excel) = @_;
$excel{ws} = Worksheet->new;
}
sub populate_worksheet {
my ($excel) = @_;
$excel{ws}->add_cell("A1", "foo");
}
This is still less clear than it might be, since you're passing %excel
by reference and then modifying it. It's better than before, since at
least you can see that's what's going on, but it's not clear from the
call that create_worksheet adds an entry but populate_worksheet modifies
a property of an existing entry. The 'correct' way to write this would
be
my $ws = create_worksheet();
populate_worksheet($ws);
sub create_worksheet {
return Worksheet->new;
}
sub populate_worksheet {
my ($ws) = @_;
$ws->add_cell("A1", "foo");
}
The important difference here is that each sub is only passed the data
it needs to do its job (and is passed *all* that data), so you can see
from the call what is going on.
> my %document = (
> "pdf" => \$pdf,
> "table" => \$table,
> );
>
> Firstly, if these are defined near the begining of the program they look
> just like globals to me! What's the difference? OK, so I can just
> declare "my %excel =();" and then have a subroutine(s) populate it on an
> ad-hoc basis, that, I suppose, looks less global.
One way to enforce discipline (until you get into the habit of doing
things right) is to put the 'main body' of your script into a 'sub
main', and then have a call to 'main()' as the only statement outside a
subroutine. That way you won't find yourself declaring variables a
globals when they could actually just be locals in 'main'.
> To avoid a whole bunch of vars being global I can see that I'm going to
> have to nest a lot of sub-routines so that I can keep scope minimal.
I'm not sure what you mean by 'nest subroutines'. If you mean putting
one named sub inside another named sub, like this
sub foo {
sub bar { ... }
}
then this is always a mistake (anon subs are a different matter, but I
don't think you're talking about that). As a general rule, you should be
passing subs the data they need to work on as parameters, and passing
the results back as the return value.
> The other thing is, if $ws, for example, was returned as a reference (I
> think I really need to see where I should return references, and where I
> should return the actual thing... if it's an object return the thing, if
> it's scalar, array or hash return a ref? maybe that's too crude)
Objects are refs already, remember, so returning an object *is*
returning a ref. (Strictly speaking, what you get back from a
constructor like ->new isn't the object itself, but a reference to the
object.)
Returning an explicit ref to a local variable like $ws is
rather rare. About the only usual case is when you've built a complex
data structure and you return a ref to avoid needing to take it apart
into a list and put it back together again in the caller.
> I
> surely shouldn't be creating a reference to it (in the hash
> assignement), so it should be "worksheet" => $ws" instead of "\$ws",
> shouldn't it?
Err... it's not clear why you think this might be necessary, but
populating a hash with refs-to-refs-to-objects would be a little
peculiar.
> Sorry if the above sounds a bit random, it's hitting the keyboard as
> it's coming to mind, and I shouldn't really be doing this now, I'm
> supposed to be working... though the work I'm supposed to be doing is
> getting this program to do what we want - it's a little chicken and egg
> here at the moment.
The compromise between 'learning to program better, which will save time
in the future' and 'solving the immediate problem in front of me right
now' not always easy to find. In your case I would say that working on
the fundamentals is worth it, at this point.
Ben
------------------------------
Date: Thu, 10 Dec 2009 16:38:19 -0600
From: Tad McClellan <tadmc@seesig.invalid>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <slrnhi2tsm.eet.tadmc@tadbox.sbcglobal.net>
Ben Morrow <ben@morrow.me.uk> wrote:
> Just use the hash entries, so instead of
>
> my $ws;
>
> create_worksheet();
> populate_worksheet();
>
> sub create_worksheet {
> # this is just an example, of course
> $ws = Worksheet->new;
> }
>
> sub populate_worksheet {
> $ws->add_cell("A1", "foo");
> }
>
> you might have
>
> my %excel;
>
> create_worksheet(\%excel);
> populate_worksheet(\%excel);
>
> sub create_worksheet {
> my ($excel) = @_;
> $excel{ws} = Worksheet->new;
Oops!
We are modifying %excel and not using the $excel parameter for anything...
$excel->{ws} = Worksheet->new;
^^
^^ I'm pretty sure this is what Ben meant to write...
> }
Which leads to one of _my_ style points: don't use similar-looking names.
If we had followed that style rule, and made the same mistake:
my $excel; # a "long" form of the name in this big scope
create_worksheet(\%excel);
populate_worksheet(\%excel);
sub create_worksheet {
my ($xl) = @_; # a "short" form of the name in this little scope
$xl{ws} = Worksheet->new;
}
then perl would have found the mistake for us (assuming "use strict").
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
------------------------------
Date: Thu, 10 Dec 2009 14:58:48 -0500
From: Sir Robert Burbridge <rburbrid@cisco.com>
Subject: Re: Unblessed reference.
Message-Id: <1260475102.571328@sj-nntpcache-2.cisco.com>
On 12/10/2009 07:34 AM, Justin C wrote:
> On 2009-12-09, Ben Morrow<ben@morrow.me.uk> wrote:
>>
>> Quoth Justin C<justin.0911@purestblue.com>:
>>> On 2009-12-08, Ben Morrow<ben@morrow.me.uk> wrote:
>>>>
>>>> Quoth Justin C<justin.0911@purestblue.com>:
>>>>>
>>>>> I'm using Spreadsheet::WriteExcel, and (I think) I've created a
>>>>> reference to the worksheet. When I try to use this elsewhere I get:
>>>>> Can't call method ... on unblessed reference at ...
>>>>>
>>>>> This is the minumum I've been able to cut the code down to (sorry it's
>>>>> not shorter). The problem line is 26. As per the Spreadsheet::WriteExcel
>>>>> documentation I've created the object, and it's a reference to that
>>>>> object that I've passed from a subroutine to Main:: to pass on to other
>>>>> subroutines.
>>>>
>>>> An object is already a reference. You don't need to take another layer
>>>> of reference, just return the object.
>>>
>>> I think I'm getting the hang. I've been using references for ages,
>>> hashrefs, arrayrefs, but whenever I use objects I get a bit confused.
>>> It's coming together slowly now that I'd started working through the OO
>>> documentation.
>>
>> Maybe you need to read perlboot. In simple terms, an object is just a
>> refrence with a bit of magic attached. Here is how you make an object:
>
> I think, now that I'm looking more at OO that perlboot and perltoot (I'm
> sure there's a third too) I'll find these two more accessible, and
> therfore probably useful. Will add them to my reading list (again).
>
>
>> my $obj = { a => 1 }; # an ordinary hashref
>> bless $obj, "My::Class"; # now it's an object
>>
>> You can still deref this object with $obj->{a}, just like any other
>> hashref, but it's considered bad style to do so from outside the class
>> that defined it. (The author of the class is entitled to change the
>> internals in the next release, without warning you.)
>>
>> However, you can also call a method on it, with $obj->method(...). This
>> is where 'My::Class' comes in: that is the package Perl will search
>> first for the method.
>
> Yup, this is where you're losing me. I'll go to the documentation, I
> fear it's going to take a little time reading, re-reading, and
> re-re-reading to get some of this stuff. As I'm getting older I find
> that practical (physicla) stuff goes in more easily, and abstract stuff
> is getting harder to understand... that's no fun when the practical
> stuff is no longer easy to do!
>
> Justin.
>
A popular phrase floating around is that Perl's OO is "bolted on".
That's actually a good way of looking at it. A perl object is just a
hash (usually) on to which you bolt some subs.
That's really all =)
Like using a glue gun to attach a pinwheel to your cell phone ... now
you can do $phone->spin()
-Sir
------------------------------
Date: Thu, 10 Dec 2009 12:13:00 -0800
From: sln@netherlands.com
Subject: Re: Unblessed reference.
Message-Id: <p2l2i5ld1ni87pjjet93k5i6cbrhsti1qq@4ax.com>
On Thu, 10 Dec 2009 14:58:48 -0500, Sir Robert Burbridge <rburbrid@cisco.com> wrote:
>On 12/10/2009 07:34 AM, Justin C wrote:
[snip]
>>
>> Yup, this is where you're losing me. I'll go to the documentation, I
>> fear it's going to take a little time reading, re-reading, and
>> re-re-reading to get some of this stuff. As I'm getting older I find
>> that practical (physicla) stuff goes in more easily, and abstract stuff
>> is getting harder to understand... that's no fun when the practical
>> stuff is no longer easy to do!
>>
>> Justin.
>>
>
>A popular phrase floating around is that Perl's OO is "bolted on".
>That's actually a good way of looking at it. A perl object is just a
>hash (usually) on to which you bolt some subs.
>
>That's really all =)
>
>Like using a glue gun to attach a pinwheel to your cell phone ... now
>you can do $phone->spin()
>
>-Sir
>
I get what you mean but, I always thought a Perl object
was an instance of a class with data and subs.
C++ an object is as little as an instance of a structure
where functions can be added or not. Of course there are
many more capabilities.
I wonder if Perl uses vtable like logic? Don't know.
-sln
------------------------------
Date: Thu, 10 Dec 2009 16:19:29 -0500
From: Sir Robert Burbridge <rburbrid@cisco.com>
Subject: Re: Unblessed reference.
Message-Id: <1260479946.268000@sj-nntpcache-3.cisco.com>
On 12/10/2009 03:13 PM, sln@netherlands.com wrote:
> I get what you mean but, I always thought a Perl object
> was an instance of a class with data and subs.
>
> -sln
Nah, it's much looser than that. A perl object is just any ol'
reference that's currently wearing a certain hat. The reference doesn't
get altered in any meaningful way (at least not that I've ever
encountered!).
Weirdly the "any ol' ref" part means you can do things like this too:
my $code_ref = sub { ... };
bless $code_ref, "Some::PKG";
### Execute some method from the "object"
$code_ref->some_method();
### Execute the "object" directly!
$code_ref->();
But anyway, check this out:
#!/usr/bin/perl
use strict;
sub hr { print '-' x 20, "\n"; }
### Create a hash ref.
my $slacker = {action=>'nuthin.'};
print $slacker, "\n";
eval {$slacker->dance()}; print $@;
eval {print $slacker->report()}; print $@;
hr;
bless $slacker, 'Blogger';
print $slacker, "\n";
eval {$slacker->dance()}; print $@;
eval {print $slacker->report()}; print $@;
hr;
bless $slacker, 'Moxie';
print $slacker, "\n";
eval {$slacker->dance()}; print $@;
eval {print $slacker->report()}; print $@;
hr;
bless $slacker, 'Blogger';
print $slacker, "\n";
eval {$slacker->dance()}; print $@;
eval {print $slacker->report()}; print $@;
### Two packages with different subs
package Blogger;
sub report {
return "I'm doin' " . shift->{'action'} . "\n";
}
package Moxie;
sub dance {
shift->{'action'} = 'a jig!';
}
1;
Run it to get this output...
-- output:
HASH(0x84ac880)
Can't call method "dance" on unblessed reference at ./f.pl line 10.
Can't call method "report" on unblessed reference at ./f.pl line 11.
--------------------
Blogger=HASH(0x84ac880)
Can't locate object method "dance" via package "Blogger" at \
./foo.pl line 16.
I'm doin' nuthin.
--------------------
Moxie=HASH(0x84ac880)
Can't locate object method "report" via package "Moxie" at \
./f.pl line 23.
--------------------
Blogger=HASH(0x84ac880)
Can't locate object method "dance" via package "Blogger" at \
./f.pl line 28.
I'm doin' a jig!
Notice that the address of the object is the same before and after all
the blessings (0x84ac880 here). Doing the same thing with Data::Dumper
would show that nothing's changing at *all* in the "object" except the
package being associated with it.
-Sir
------------------------------
Date: Thu, 10 Dec 2009 22:24:03 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Unblessed reference.
Message-Id: <3198v6-nb42.ln1@osiris.mauzo.dyndns.org>
Quoth Sir Robert Burbridge <rburbrid@cisco.com>:
> On 12/10/2009 03:13 PM, sln@netherlands.com wrote:
> > I get what you mean but, I always thought a Perl object
> > was an instance of a class with data and subs.
>
> Nah, it's much looser than that. A perl object is just any ol'
> reference that's currently wearing a certain hat. The reference doesn't
> get altered in any meaningful way (at least not that I've ever
> encountered!).
The *ref* itself isn't changed at all. The object (the thing the ref
points to) just has the string you supply stuffed into its 'class' slot.
You can create a completely fresh ref, and it's still an object:
my $o = bless {}, "Foo";
my $o2 = \%$o;
# $o2 is a brand new ref to the same object
> Weirdly the "any ol' ref" part means you can do things like this too:
> my $code_ref = sub { ... };
> bless $code_ref, "Some::PKG";
> ### Execute some method from the "object"
> $code_ref->some_method();
> ### Execute the "object" directly!
> $code_ref->();
Oh, you can do *much* weirder things than that :). Check out the source
for IO::Handle and related modules sometime.
Ben
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 2714
***************************************