[31469] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 2721 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Dec 14 18:09:44 2009

Date: Mon, 14 Dec 2009 15:09:10 -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           Mon, 14 Dec 2009     Volume: 11 Number: 2721

Today's topics:
        Get remote IP in self-calling script <dimke.fax@uni.de>
    Re: Get remote IP in self-calling script <OJZGSRPBZVCX@spammotel.com>
    Re: Get remote IP in self-calling script <dimke.fax@uni.de>
    Re: Get remote IP in self-calling script <glex_no-spam@qwest-spam-no.invalid>
    Re: Get remote IP in self-calling script <OJZGSRPBZVCX@spammotel.com>
    Re: Get remote IP in self-calling script <dimke.fax@uni.de>
    Re: Get remote IP in self-calling script <OJZGSRPBZVCX@spammotel.com>
    Re: How big do your programs get before you modularise  <hjp-usenet2@hjp.at>
    Re: regex find then replace - a cleaner approach? <pgovern@u.washington.edu>
    Re: Trying to avoid passing params to subs through glob <rburbrid@cisco.com>
    Re: Trying to avoid passing params to subs through glob <uri@StemSystems.com>
    Re: Trying to avoid passing params to subs through glob <rburbrid@cisco.com>
    Re: Trying to avoid passing params to subs through glob <OJZGSRPBZVCX@spammotel.com>
    Re: Trying to avoid passing params to subs through glob <OJZGSRPBZVCX@spammotel.com>
    Re: Trying to avoid passing params to subs through glob <uri@StemSystems.com>
    Re: Trying to avoid passing params to subs through glob <OJZGSRPBZVCX@spammotel.com>
    Re: Trying to avoid passing params to subs through glob <uri@StemSystems.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: 14 Dec 2009 21:14:24 GMT
From: "Markus R." =?iso-8859-1?q?Ke=DFler?= <dimke.fax@uni.de>
Subject: Get remote IP in self-calling script
Message-Id: <4b26aab0$0$7629$9b4e6d93@newsspool1.arcor-online.net>

Hi there,

I've written a little perl script that handles text like a webmail gui 
does. It is accessible via webbrowser from the internet.

When the script is invoked without parameter if creates the neccessary 
html code for a kind of input mask for entering the text, as well as the 
buttons for "send" etc. So there's no need for a html file creating the 
input form and from which the script is invoked.

It _does_ work, so far.

But, because the script is called from itself, $ENV{'REMOTE_ADDR'} always 
writes the IP of the _SERVER_ into the logfile, rather than the user's 
one :-(

Any idea how to get around that?

Thanks for any hint!

Best regards,

Markus

-- 
Please reply to group only.
For private email please use http://www.dipl-ing-kessler.de/email.htm


------------------------------

Date: Mon, 14 Dec 2009 22:21:54 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
To: =?iso-8859-15?Q?Markus_R=2E_Ke=DFler?= <dimke.fax@uni.de>
Subject: Re: Get remote IP in self-calling script
Message-Id: <op.u4x5msw2mk9oye@frodo>

On Mon, 14 Dec 2009 22:14:24 +0100, Markus R. Keßler <dimke.fax@uni.de>  
wrote:

> But, because the script is called from itself,

Why?

> Any idea how to get around that?

If you do a local http request on the server (using LWP, I assume), then  
there is no sane way to fake another IP address into the logfile of your  
web server. You could of course pass the original IP in a CGI parameter  
and log it yourself. But why would you do a local http request in the  
first place? I've done this in some cases where some script uses another  
one, but calling *itself* seems not necessary.

> Thanks for any hint!

Show your code...


------------------------------

Date: 14 Dec 2009 21:41:45 GMT
From: "Markus R." =?iso-8859-1?q?Ke=DFler?= <dimke.fax@uni.de>
Subject: Re: Get remote IP in self-calling script
Message-Id: <4b26b119$0$7629$9b4e6d93@newsspool1.arcor-online.net>

Am Mon, 14 Dec 2009 22:21:54 +0100 schrieb Jochen Lehmeier:

> On Mon, 14 Dec 2009 22:14:24 +0100, Markus R. Keßler <dimke.fax@uni.de>
> wrote:
> 
>> But, because the script is called from itself,
> 
> Why?

I just want to have one file doing the job.
When I started writing web applications in most cases I wrote a html file 
which invoked a perl script, but this way I always had to modify two 
files for any changes. I had to modify the html one for changing the 
layout, and I had to modify the perl script which handled the input from 
the htm file.

>> Any idea how to get around that?
> 
> If you do a local http request on the server (using LWP, I assume), then
> there is no sane way to fake another IP address into the logfile of your
> web server. You could of course pass the original IP in a CGI parameter
> and log it yourself. But why would you do a local http request in the
> first place? I've done this in some cases where some script uses another
> one, but calling *itself* seems not necessary.

Well, I already thought about passing the IP within a "hidden" variable 
from the calling instance of the script to the called one.
Sure, this would work, but in that case I rely on a variable that could 
be faked when calling the script via curl etc.

> Show your code...

For instance, this

http://www.dipl-ing-kessler.de/developer/freigabe/compat/index.htm

is an example of one of my self-calling scripts.

Best regards,

Markus

-- 
Please reply to group only.
For private email please use http://www.dipl-ing-kessler.de/email.htm


------------------------------

Date: Mon, 14 Dec 2009 16:09:16 -0600
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: Get remote IP in self-calling script
Message-Id: <4b26b78d$0$89869$815e3792@news.qwest.net>

Markus R. Keßler wrote:
> Am Mon, 14 Dec 2009 22:21:54 +0100 schrieb Jochen Lehmeier:
> 
>> On Mon, 14 Dec 2009 22:14:24 +0100, Markus R. Keßler <dimke.fax@uni.de>
>> wrote:
>>
>>> But, because the script is called from itself,
>> Why?
> 
> I just want to have one file doing the job.
> When I started writing web applications in most cases I wrote a html file 
> which invoked a perl script, but this way I always had to modify two 
> files for any changes. I had to modify the html one for changing the 
> layout, and I had to modify the perl script which handled the input from 
> the htm file.

That's usually a good design, if the template is flexible enough
to handle different parameters. Look at using a template module.  Plenty
to choose from on CPAN.  Template, HTML::Simple, HTML::Mason, etc.
or simply use the CGI module to generate your HTML.

> 
>>> Any idea how to get around that?
>> If you do a local http request on the server (using LWP, I assume), then
>> there is no sane way to fake another IP address into the logfile of your
>> web server. You could of course pass the original IP in a CGI parameter
>> and log it yourself. But why would you do a local http request in the
>> first place? I've done this in some cases where some script uses another
>> one, but calling *itself* seems not necessary.
> 
> Well, I already thought about passing the IP within a "hidden" variable 
> from the calling instance of the script to the called one.
> Sure, this would work, but in that case I rely on a variable that could 
> be faked when calling the script via curl etc.
> 
>> Show your code...
> 
> For instance, this
 ...
> 
> is an example of one of my self-calling scripts.

ahhhh.. that's not your code, that's possibly the output of
your code. Show us the code for your program.  You don't have to
post everything, simply make a small/short script that
would show us what you're currently doing.


You can pass arguments to your program, instead of
doing another HTTP request.

perldoc perlopentut
perldoc IPC::Open3
perldoc -f system
perldoc -f do


------------------------------

Date: Mon, 14 Dec 2009 23:14:37 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
Subject: Re: Get remote IP in self-calling script
Message-Id: <op.u4x72nn2mk9oye@frodo>

On Mon, 14 Dec 2009 22:41:45 +0100, Markus R. Keßler <dimke.fax@uni.de>  
wrote:

>>> But, because the script is called from itself,
>>
>> Why?
>
> I just want to have one file doing the job.

You mean your script outputs the <form> if there are no input parameters;  
if there are input parameters (as submitted by the form) you process them.

That's fine and standard.

If you say "the script is called from itself" I interpret it as "the  
script calls itself" (maybe using system()) or whatever; also, for your  
server's IP to appear in the Apache (?) logfile, the HTTP connection for  
the request would have to originate from the server. But, looking at your  
source code, it looks like I misunderstood you there.

> For instance, this
>
> http://www.dipl-ing-kessler.de/developer/freigabe/compat/index.htm

You really want to use CGI instead of doing all of the basic CGI stuff  
yourself.

I also fail to see how you could end up with your server's IP in the  
logfile. The second request seems to come from the browser just fine, so  
Apache should log the user's IP.


------------------------------

Date: 14 Dec 2009 22:49:39 GMT
From: "Markus R." =?iso-8859-1?q?Ke=DFler?= <dimke.fax@uni.de>
Subject: Re: Get remote IP in self-calling script
Message-Id: <4b26c102$0$7629$9b4e6d93@newsspool1.arcor-online.net>

Am Mon, 14 Dec 2009 23:14:37 +0100 schrieb Jochen Lehmeier:

> On Mon, 14 Dec 2009 22:41:45 +0100, Markus R. Keßler <dimke.fax@uni.de>
> wrote:
> 
>>>> But, because the script is called from itself,
>>>
>>> Why?
>>
>> I just want to have one file doing the job.
> 
> You mean your script outputs the <form> if there are no input
> parameters; if there are input parameters (as submitted by the form) you
> process them.

Yes, that's what the script does!

So it was slightly misleading to say "self-calling". Sorry.

> That's fine and standard.
> 
> If you say "the script is called from itself" I interpret it as "the
> script calls itself" (maybe using system()) or whatever; also, for your
> server's IP to appear in the Apache (?) logfile, the HTTP connection for
> the request would have to originate from the server. But, looking at
> your source code, it looks like I misunderstood you there.

> I also fail to see how you could end up with your server's IP in the
> logfile. The second request seems to come from the browser just fine, so
> Apache should log the user's IP.

Yes, there's the Apache logfile also, which shows the "real" IP in one 
line when the script is called for the first time and without parameter.

And the following line, when clicking on "submit" the "remote address" 
environment variable contains the IP of the server.

So, getting the "real" user's IP can be easily done by grepping the 
Apache logfile. But:

- for convenience purposes I'd like to have a separate logfile

- the user could load the script (without parameters) and leave the 
browser for any time period.
So, when clicking the "submit" button, let's say, hours later, it would 
be nearly impossible to determine which call of the script (with 
parameters) is related to the first call with the "real" user's IP.

The background is: I wrote a little "diary" application which stores my 
ideas, and, at least I want to see which "hacking attempts" occur to this 
application. That's the point.

Any idea how to get the "real" IP at _any_ time the script is called 
directly or indirectly?

Best regards,

Markus

-- 
Please reply to group only.
For private email please use http://www.dipl-ing-kessler.de/email.htm


------------------------------

Date: Mon, 14 Dec 2009 23:59:49 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
Subject: Re: Get remote IP in self-calling script
Message-Id: <op.u4x95zbzmk9oye@frodo>

On Mon, 14 Dec 2009 23:49:39 +0100, Markus R. Keßler <dimke.fax@uni.de>  
wrote:

> And the following line, when clicking on "submit" the "remote address"
> environment variable contains the IP of the server.

How is that possible? If the user clicks "submit", the user's browser  
connects to your Apache, which logs the remote IP (all this does not  
involve Perl yet, as your web server will log independent from what  
happens inside the CGI script).

> Any idea how to get the "real" IP at _any_ time the script is called
> directly or indirectly?

The remote IP should already be logged, and a workaround should absolutely  
not be necessary.

Maybe you could make your code as short as possible (i.e., reduce  
everything to the barest minimum of stuff; only one input field etc.).  
Post your perl code together with the two form HTML page (the first one,  
which is displayed when there are no CGI parameters) and the log file  
snippet for the two requests. Then we can take a look at it.


------------------------------

Date: Mon, 14 Dec 2009 21:20:31 +0100
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: How big do your programs get before you modularise most of it?
Message-Id: <slrnhid7gf.3mf.hjp-usenet2@hrunkner.hjp.at>

On 2009-12-14 17:39, Jochen Lehmeier <OJZGSRPBZVCX@spammotel.com> wrote:
> On Mon, 14 Dec 2009 18:31:51 +0100, Martijn Lievaart <m@rtij.nl.invlalid>  
> wrote:
>
>> Refactoring your code if you get it wrong is a basic part of writing
>> code. Don' put it off, just do it.
>
> ... while running your unit tests frequently.

Refactoring is a good opportunity to add unit tests if you don't have
them already. Before you start rewriting code ask yourself what that
code should do. Then write tests which test your assumptions. Then start
rewriting the code. 

Devel::Cover helps you to find out whether the code you are rewriting is
already covered by tests.

	hp



------------------------------

Date: Mon, 14 Dec 2009 11:16:09 -0800 (PST)
From: patrick <pgovern@u.washington.edu>
Subject: Re: regex find then replace - a cleaner approach?
Message-Id: <2e985c52-9112-49c3-b15c-0d7b3d741b95@u16g2000pru.googlegroups.com>

On Dec 11, 7:42=A0am, "John" <john1...@yahoo.com> wrote:
> Hi
>
> I have
>
> if ($SIC =3D~m |20745|) {
> =A0 =A0 =A0 =A0$SIC =3D~s |20745|567345|g;
> =A0 =A0 =A0 =A0$sql=3D"UPDATE $table SET SIC=3D'$SIC' WHERE id=3D'$id'"
>
> }
>
In Oracle you might just use (if doing the entire table):
update $table
   set SIC =3D replace(SIC, '20745', '567345')
 where SIC like '%20745%'

=3D=3D=3D=3D>Pat



------------------------------

Date: Mon, 14 Dec 2009 15:47:39 -0500
From: Sir Robert Burbridge <rburbrid@cisco.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <1260823618.230906@sj-nntpcache-3.cisco.com>

On 12/14/2009 01:46 PM, Uri Guttman wrote:
>>>>>> "SRB" == Sir Robert Burbridge<rburbrid@cisco.com>  writes:
>
>    SRB>  Although, I've actually found this a very helpful paradigm:
>
> actually that is a poor paradigm.
>
>    SRB>  sub do_something {
>    SRB>      ...
>    SRB>      my $handler = sub {
>    SRB>          ...
>    SRB>      };
>
>    SRB>      if ($cond_a) {
>    SRB>          return $handler->(do_a());
>    SRB>      } elsif ($cond_b) {
>
> why the else (of the if) when you just returned? make it cleaner by just
> falling through to a plain if.
>
>    SRB>          return $handler->(do_b());
>    SRB>      } else {
>    SRB>          return $handler->(do_c());
>    SRB>      }
>    SRB>  }
>
> better yet, use a dispatch table. i hate elsif's and try to never use
> them. they are a marker for poor logic. hell, i eschew else as well. in
> over 10k lines in one project i had about 3 elsif's and 11 else's. and
> the code is very readable. it is just done with very clean logic and
> code flow.
>
> uri
>

Definitely =)  Conditionals were mostly just fodder for the sake of the 
anonymous sub (which was the major point).  Mostly I use this kind of 
thing for failure routines:
     if (my $result = try_something()) {
         handle_success($result);
     } elsif (my $result = try_fallback()) {
         handle_succesS($result);
     }
and so on ... I don't really have a good paradigm for that kind of thing 
that would involve a dispatch table though (is there one?).

-Sir






------------------------------

Date: Mon, 14 Dec 2009 16:04:27 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <87my1lz2qs.fsf@quad.sysarch.com>

>>>>> "SRB" == Sir Robert Burbridge <rburbrid@cisco.com> writes:

  SRB> On 12/14/2009 01:46 PM, Uri Guttman wrote:
  SRB> if ($cond_a) {
  SRB> return $handler->(do_a());
  SRB> } elsif ($cond_b) {
  >> 
  >> why the else (of the if) when you just returned? make it cleaner by just
  >> falling through to a plain if.
  >> 
  SRB> return $handler->(do_b());
  SRB> } else {
  SRB> return $handler->(do_c());
  SRB> }
  SRB> }
  >> 
  >> better yet, use a dispatch table. i hate elsif's and try to never use
  >> them. they are a marker for poor logic. hell, i eschew else as well. in
  >> over 10k lines in one project i had about 3 elsif's and 11 else's. and
  >> the code is very readable. it is just done with very clean logic and
  >> code flow.

  SRB> Definitely =)  Conditionals were mostly just fodder for the sake of
  SRB> the anonymous sub (which was the major point).  Mostly I use this kind
  SRB> of thing for failure routines:
  SRB>     if (my $result = try_something()) {
  SRB>         handle_success($result);
  SRB>     } elsif (my $result = try_fallback()) {
  SRB>         handle_succesS($result);
  SRB>     }
  SRB> and so on ... I don't really have a good paradigm for that kind of
  SRB> thing that would involve a dispatch table though (is there one?).

you can still drop the elsif and make them if's if the handlers are done
and you need to exit. that alone makes for a better coding style.

as for that try/handle stuff, if it is as regular as you show, then a
simple table/loop will do it better:

	my @try_subs = ( \&try_foo, \&try_bar, ... ) ;

	foreach my $try ( @try_subs ) {

		my $result = $try->() ;
		next unless $result ;

		handle_success( $result ) ;
		last ;
	}

nary an else or elsif in the code!

thanx,

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: Mon, 14 Dec 2009 16:11:09 -0500
From: Sir Robert Burbridge <rburbrid@cisco.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <1260825027.822715@sj-nntpcache-3.cisco.com>

> as for that try/handle stuff, if it is as regular as you show, then a
> simple table/loop will do it better:
>
> 	my @try_subs = ( \&try_foo, \&try_bar, ... ) ;
>
> 	foreach my $try ( @try_subs ) {
>
> 		my $result = $try->() ;
> 		next unless $result ;
>
> 		handle_success( $result ) ;
> 		last ;
> 	}
>
> nary an else or elsif in the code!
>
> thanx,
>
> uri
>

Hey, that's a pretty good paradigm.  Thanks =)

-Sir




------------------------------

Date: Mon, 14 Dec 2009 22:18:51 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <op.u4x5hpy7mk9oye@frodo>

On Mon, 14 Dec 2009 19:46:14 +0100, Uri Guttman <uri@stemsystems.com>  
wrote:

> in over 10k lines in one project i had about 3 elsif's and 11 else's.

I understand your trouble with elsif (well, at least I can think of cases  
where elsif may not be optimal).

But "else"? How could "else" possibly be a sign of bad logic?


------------------------------

Date: Mon, 14 Dec 2009 22:40:34 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <op.u4x6hwdsmk9oye@frodo>

On Mon, 14 Dec 2009 22:04:27 +0100, Uri Guttman <uri@stemsystems.com>  
wrote:

>   SRB>     if (my $result = try_something()) {
>   SRB>         handle_success($result);
>   SRB>     } elsif (my $result = try_fallback()) {
>   SRB>         handle_succesS($result);
>   SRB>     }

> 	my @try_subs = ( \&try_foo, \&try_bar, ... ) ;
>
> 	foreach my $try ( @try_subs ) {
>
> 		my $result = $try->() ;
> 		next unless $result ;
>
> 		handle_success( $result ) ;
> 		last ;
> 	}
>
> nary an else or elsif in the code!

I guess if we would work in a team, we would regularly have heated  
discussions on things like this. Replacing a standard, efficient, easy to  
parse (mentally), absolutely normal coding style with a rather convoluted  
one, just for the abstract goal of avoiding "else" and "elsif" (*)...  
well, I have no useful, public-compatible comment really.

Besids, your pattern breaks down as soon as your functions take different  
arguments, or your handle_success() differ from each other, though I guess  
you could work around that with closures too, if you wanted.

Note, I do not recall that the OP mentioned lots and lots of elsif's -  
only 2 or maybe 3. For larger numbers of cases, and especially when  
re-used, this pattern might be kind of useful, but not for simple cases  
like this, and not just for getting rid of els(e|if).

Aside from that,

    my $result = try_something() || try_fallback();
    handle_success($result) if $result;

would be the Perl-like variant I'd use (or straigtforward "elsif", just  
like SRB), which scales perfectly to large numbers of try_()'s if you  
insert line breaks in strategical places.


------------------------------

Date: Mon, 14 Dec 2009 16:51:18 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <878wd5z0kp.fsf@quad.sysarch.com>

>>>>> "JL" == Jochen Lehmeier <OJZGSRPBZVCX@spammotel.com> writes:

  JL> On Mon, 14 Dec 2009 19:46:14 +0100, Uri Guttman <uri@stemsystems.com>
  JL> wrote:

  >> in over 10k lines in one project i had about 3 elsif's and 11 else's.

  JL> I understand your trouble with elsif (well, at least I can think of
  JL> cases  where elsif may not be optimal).

  JL> But "else"? How could "else" possibly be a sign of bad logic?

not a sign of bad logic but of inefficient logic in perl.

my favorite counter example is this style which is all too common:

you enter a sub and have a validity check for something and then you do
the work if the data is ok:

	if ( valid() ) {

		do lots of code here 
	}
	else {
		return -1 ;
	}

	return $result ;

vs my style:

	return -1 unless valid() ;

	lots of code
	return $result ;


look ma, no else!! no else is needed!! it is shorter, no extra block
entries, no extra indent, no wasted pixels for the {} chars!

you do your checking and get out immediately if bad. then the main good
work is done inline and not in an indented block. perl allows and
encourages this style with statement modifiers and good flow control
ops.

there are many variations on that style but they all eschew else
statements. you just don't need them that often in good perl. most of
the time elses are used for error cases. other times a conditional
expression is better (that is another commonly abused thing, else's
assigning to the same var as the then clause). if you show me code with
lots of else's i can usually rewrite it better without them.

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: Mon, 14 Dec 2009 23:44:50 +0100
From: "Jochen Lehmeier" <OJZGSRPBZVCX@spammotel.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <op.u4x9g0ppmk9oye@frodo>

On Mon, 14 Dec 2009 22:51:18 +0100, Uri Guttman <uri@stemsystems.com>  
wrote:

> not a sign of bad logic but of inefficient logic in perl.

Define "bad", define "inefficient". Try to avoid the term "logic" please,  
it is much too big in this context, c/f http://en.wikipedia.org/wiki/Logic.

> you enter a sub and have a validity check for something and then you do
> the work if the data is ok:
>
> 	if ( valid() ) {
>
> 		do lots of code here
> 	}
> 	else {
> 		return -1 ;
> 	}
>
> 	return $result ;
>
> vs my style:
>
> 	return -1 unless valid() ;
>
> 	lots of code
> 	return $result ;

> look ma, no else!! no else is needed!!

Well, this is completely different code from what we talked about before,  
and you didn't mention my remarks on the original topic at all (Logical  
Fallacy: Irrelevant Conclusion). Of course your second code is shorter  
than the longer code up there (and I've written enough fragements closer  
to your second than your first), but I still fail to see how this is so  
specifically *because* there is no "else" (Logical Fallacies: Affirming  
the Consequent, Denying the Antecedent, and maybe Non Sequitur). And while  
I am with you in that your second code is better than the first, you still  
have to convince me that your second code is "better" than (just to name  
an example)

   my $result=-1;
   if (valid())
   {
     lots of code
   }
   return $result;

You seem to be very focused on "else". I still fail to see why. There are  
many ways to write code with or without "else", all with different  
lengths, your measurement of code simply seems to consist of the number of  
bytes and number of "else"s.

> you do your checking and get out immediately if bad. then the main good
> work is done inline and not in an indented block. perl allows and
> encourages this style with statement modifiers and good flow control
> ops.

Yes, yes, but go back to the original topic please - very different stuff  
back there (Logical Fallacy: Fallacy of Many Questions or Loaded Question)

> there are many variations on that style but they all eschew else
> statements. you just don't need them that often in good perl.[...]
> if you show me code with
> lots of else's i can usually rewrite it better without them.

For your definition of "better".

The reason I reply here and try to argue with you is that you make "else"  
out to be totally bad and evil, like someone saying "goto is evil" (the  
latter being true ;-) ). I would hate for some Perl newcomer to grow up  
with FUD or hearsay like this. Saying "a rather short than long coding  
style, getting out of subs ASAP" is perfectly fine with me. But saying  
"avoid else at all costs" is not.

You are correct in saying that there is the long-winded coding style of  
people who are not familiar with the usual Perl idioms which can be used  
to make Perl code short. But there is nothing at all specifically pointing  
to "else" in that reasoning. And it is absolutely not true that in all  
circumstances the shorter code is "better".

Besides, consider: you suggest to work a lot with "return" or "last"  
mingled in between other statements. This is one thing which surely leads  
to shorter code, but also leads very quickly to code which is much harder  
to maintain, since it gets harder to see the flow of execution at a  
glance. I.e., if I have a sub that does *not* contain any "return" or  
"last", then I can be absolutely sure that the flow of execution will, at  
some point, arrive at the end of the method; and I can be absolutely sure  
that I can add code there that will be executed after everything else in  
that sub (for example, something which modifies, logs or validates the  
return code). With frequent "return" and "last", this gets harder. (Yes, I  
am purposefully ignoring "die" here).

There are is also the Theory of Computation, which, for example, concerns  
itself with proofs of correctness. In those areas, if/else is often *much*  
easier to work with than return/last.

Check out LISP, just to broaden the horizon. The language does not even  
have the concept of "return" or "last" at all, and heavily uses "else".  
But it's still *very* logical, indeed.

PS: Sorry for the OT Logic stuff, folks. ;-)


------------------------------

Date: Mon, 14 Dec 2009 18:01:14 -0500
From: "Uri Guttman" <uri@StemSystems.com>
Subject: Re: Trying to avoid passing params to subs through globals
Message-Id: <876389xirp.fsf@quad.sysarch.com>

>>>>> "JL" == Jochen Lehmeier <OJZGSRPBZVCX@spammotel.com> writes:

  JL> On Mon, 14 Dec 2009 22:51:18 +0100, Uri Guttman <uri@stemsystems.com>
  JL> wrote:

  >> not a sign of bad logic but of inefficient logic in perl.

  JL> Define "bad", define "inefficient". Try to avoid the term "logic"
  JL> please,  it is much too big in this context, c/f
  JL> http://en.wikipedia.org/wiki/Logic.

i use logic as in the decisions made in flow control. those are all
logical choices. it is a fine term for this.

  >> you enter a sub and have a validity check for something and then you do
  >> the work if the data is ok:
  >> 
  >> if ( valid() ) {
  >> 
  >> do lots of code here
  >> }
  >> else {
  >> return -1 ;
  >> }
  >> 
  >> return $result ;
  >> 
  >> vs my style:
  >> 
  >> return -1 unless valid() ;
  >> 
  >> lots of code
  >> return $result ;

  >> look ma, no else!! no else is needed!!

  JL> Well, this is completely different code from what we talked about
  JL> before,  and you didn't mention my remarks on the original topic at
  JL> all (Logical  Fallacy: Irrelevant Conclusion). Of course your second
  JL> code is shorter  than the longer code up there (and I've written
  JL> enough fragements closer  to your second than your first), but I still
  JL> fail to see how this is so  specifically *because* there is no "else"
  JL> (Logical Fallacies: Affirming  the Consequent, Denying the Antecedent,
  JL> and maybe Non Sequitur). And while  I am with you in that your second
  JL> code is better than the first, you still  have to convince me that
  JL> your second code is "better" than (just to name  an example)

it is faster as in no block entry which costs you in perl.

it is shorter so it is easier to read on a screen

it is simpler as you don't need to check inside blocks for what is
happening and where.

easier to follow the MAIN logic which doing the work as you already
handled the easy error exit case. no worries about what ELSE should be
done as there is no else clause.

one less indent makes it easier to read and you can use longer lines
with fewer wrapped lines. that also makes the code shorter and easier to read.

is that enough to qualify it as BETTER code? 5 good reasons with others
i can scrounge up if needed.

  JL>   my $result=-1;
  JL>   if (valid())
  JL>   {
  JL>     lots of code
  JL>   }
  JL>   return $result;

  JL> You seem to be very focused on "else". I still fail to see why. There
  JL> are  many ways to write code with or without "else", all with
  JL> different  lengths, your measurement of code simply seems to consist
  JL> of the number of  bytes and number of "else"s.

i don't focus on else. i just easily code away from it. it takes zero
effort for me to do it and it generates better code by the above
reasons. it is the coding style i teach for perl and it usually wins
over most who learn it.


  >> you do your checking and get out immediately if bad. then the main good
  >> work is done inline and not in an indented block. perl allows and
  >> encourages this style with statement modifiers and good flow control
  >> ops.

  JL> Yes, yes, but go back to the original topic please - very different
  JL> stuff  back there (Logical Fallacy: Fallacy of Many Questions or
  JL> Loaded Question)

huh?? we are talking a minimal change in style to lower the else count
and make better code. there is no loaded question nor fallacy here. it
is a proven style improvement. simple and effective.

  >> there are many variations on that style but they all eschew else
  >> statements. you just don't need them that often in good perl.[...]
  >> if you show me code with
  >> lots of else's i can usually rewrite it better without them.

  JL> For your definition of "better".

and i get paid to judge code so my word has backing on this. i rate code
for recruitment and for code review projects. too many elses can always
be improved. it is just one of the many things i see which can be
improved. hell, my code can be improved. please do so. my cpan id is
URI. go for it and publish it here. if you show me better code, i will
use it gladly. but you have to also prove it to be better. i know i can
back up my code against weak attacks.

  JL> The reason I reply here and try to argue with you is that you make
  JL> "else" out to be totally bad and evil, like someone saying "goto
  JL> is evil" (the latter being true ;-) ). I would hate for some Perl
  JL> newcomer to grow up with FUD or hearsay like this. Saying "a
  JL> rather short than long coding style, getting out of subs ASAP" is
  JL> perfectly fine with me. But saying "avoid else at all costs" is
  JL> not.

not evil, just not needed as often as it is commonly used. it is needed
but just rarely. i don't go out of my way to force no elses. i just can
do it naturally in perl. in other langs it wouldn't be as easy. this is
a perl style point, not a general thing against elses like with no gotos.

  JL> You are correct in saying that there is the long-winded coding style
  JL> of  people who are not familiar with the usual Perl idioms which can
  JL> be used  to make Perl code short. But there is nothing at all
  JL> specifically pointing  to "else" in that reasoning. And it is
  JL> absolutely not true that in all  circumstances the shorter code is
  JL> "better".

shorter code is generally better code given that it isn't forced into
obsfucation. there is a limit but so much code is long winded and can be
easily improved by shortening it.

  JL> Besides, consider: you suggest to work a lot with "return" or "last"
  JL> mingled in between other statements. This is one thing which surely
  JL> leads  to shorter code, but also leads very quickly to code which is
  JL> much harder  to maintain, since it gets harder to see the flow of
  JL> execution at a  glance. I.e., if I have a sub that does *not* contain
  JL> any "return" or  "last", then I can be absolutely sure that the flow
  JL> of execution will, at  some point, arrive at the end of the method;
  JL> and I can be absolutely sure  that I can add code there that will be
  JL> executed after everything else in  that sub (for example, something
  JL> which modifies, logs or validates the  return code). With frequent
  JL> "return" and "last", this gets harder. (Yes, I  am purposefully
  JL> ignoring "die" here).

then your code is too complex. i keep things short and sweet and flow
control is everything in doing that.

  JL> There are is also the Theory of Computation, which, for example,
  JL> concerns  itself with proofs of correctness. In those areas, if/else
  JL> is often *much*  easier to work with than return/last.

who cares about that when working in the real world?

  JL> Check out LISP, just to broaden the horizon. The language does not
  JL> even  have the concept of "return" or "last" at all, and heavily uses
  JL> "else".  But it's still *very* logical, indeed.

lisp sucks donkey balls. and i know from plenty of experience in
it. lisp is for computers. perl is for people. your choice!

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: 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 2721
***************************************


home help back first fref pref prev next nref lref last post