TCLUG Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [TCLUG:2586] perl question



> > Ben Luey wrote:
> > >
> > > In perl is there a good way to write a script such that
> > >
> > > if A and if B, then C
> > > if not A then C
> > > if A and not B then nothing?

   You said you had trouble understanding subroutines.  It's really quite
easy -- since 'C' is the bit that's going to save you the most typing by
subroutining, I'd do it thusly:

	if ($A ne 'stringA') { C(); }       # If A is *not* true, then B doesn't
matter.  Do C.
	elsif ($B eq 'stringB') { C(); }    # Otherwise, do C only if B is true.
	exit;

	sub C

		code for subroutine C goes here;
	}

   That's really all there is to it.  Of course, this is bad form for
several reasons, which I won't bore you with, but it should work, and it's
easy to read.  Save the short-circuiting and variable scoping for when
you've got a few working projects under your belt.

	I looked at your code and saw some other stuff that might be causing
problems -- like the negation of =~ is !~, not !=~.  But I think a totally
different approach may be called for.  I'll see if I can figure something
out.

   Now for some boring, nitpicky, and entirely irrelevant stuff.
> >
> > if (!A || (A && (&B()))) {    # that last ampersand means 'call
subroutine'
>
> Actually, the & does not mean 'call subroutine' it means 'call subroutine
> with local stack'.  Usually this is not the desired intention.

That's true, but since it was called as &B(), not &B,  B gets a new stack...
From the perl FAQ:

"Q: What's the difference between calling a function as &foo and foo()?

A: When you call a function as &foo, you allow that function access to your
current @_ values, and you by-pass prototypes. That means that the function
doesn't get an empty @_, it gets yours! While not strictly speaking a bug
(it's documented that way in the perlsub manpage), it would be hard to
consider this a feature in most cases.

When you call your function as &foo(), then you do get a new @_, but
prototyping is still circumvented.

Normally, you want to call a function using foo(). You may only omit the
parentheses if the function is already known to the compiler because it
already saw the definition (use but not require), or via a forward reference
or use subs declaration. Even in this case, you get a clean @_ without any
of the old values leaking through where they don't belong. "