Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- From: "Tassilo v. Parseval" <tassilo.von.parseval@xxxxxxxxxxxxxx>
- Date: Fri, 19 Aug 2005 11:00:04 +0200
Also sprach Veli-Pekka Tätilä:
> Tassilo v. Parseval wrote:
>
> defencive programming:
>> So PHP is offensive. ;-)
> Yup, at least V4 is <smile>. But as to defencive programming in Perl, I've
> found these two lines invaluable:
>
> use strict;
> use warnings FATAL => qw|all|;
>
> Writing code with speech it is far too easy to accidentally mistype an
> identifier and try introducing a new variable in the middle of a
> print-statement or something. And as to making warnings die, it prevents you
> from fixing things lazily and catches subtle initialization bugs, very nice.
> Another benefit is knowing as soon as something goes wrong. As the screen
> reader's focus can be in one GUI widget at a time and the console app I'm
> doing runs in the background, dying quickly, forces me to actually notice
> the warnings. It would be even better if I could be warned audibly by
> emiting the bell char \a to the console when-ever this does happen. However,
> I reckon that's a no-can-do in Win32 as signals aren't implemented and END
> blocks not run when you die. Perhaps using eval, then.
Don't the pseudo-signals __WARN__ and __DIE__ work on windows, too?
With them:
use warningsd FATAL => 'all';
$SIG{ __DIE__ } = sub {
for (1 .. 10) {
print STDERR "\a"; # need auto-flushed handle here
select undef, undef, undef, 0.2;
}
}
Or use one of the Win32 modules to emmit this annoying "oh-oh" Windows
system sound. :-)
> benefits of dynamic typing:
>> Consider a module that is used to write XML tags as generically as
>> possible. <snip> <snip> all you need is one special
>> method to handle it all. <snip> generate and compile
>> the requested method on the fly:
> I see, your auto load example is pretty impressive. Still, as they say
> there's more than one way to do it, wouldn't it be easier foor the caller if
> there was one createTag method whose first argument was the name of the tag.
> No auto-load or pollution of the callers namespace needed. But then again
> the other benefits you mentioned will be lost and you don't necessarily have
> to export the methods.
Yes, having a createTag() method is how less dynamic languages would do
it. With the expected consequences for the API.
> ah, I think I now know another example of auto loading. The Win32::OLE
> module that I'm using a lot enables you to load in an OLE type library and
> after that the constructed object will magically have method and property
> names corresponding to those of the type library. And calling non-existant
> methods dies cleanly, too. I was really awed when I saw this. I cannot think
> of a way to achieve the same thing in Java, for instance, even if you could
> use reflection and polymorphism. Sure you might be able to have some
> dispatcher method whose first argument is the property or method being
> operated on, as in the previous example, but that doesn't look as smooth as
> in Perl. Finally, I'm greatful that Perl programmers generally don't do as
> much operator over-loading as C++-programmers, because it can be very
> confusing if overused.
Note that tied hashes or arrays are conceptually overloading the
subscript operator. The C++ equivalent would be overloading the '[]'
operator. So if you consider tying as overloading, then it is in fact
common in Perl.
However, Perl programmers seem to be less hooked on overloading
operators the classical way (by using the 'overload' pragma).
> Prototypes:
>> Perl does have forward-declarations as well. The case above works if the
>> function definitions comes before the code that calls this function.
> I just tried your example and noticed the same thing on my own yesterday.
> Argh as in C again, I like the Java method where the compiler doesn't force
> you to type in the same thing twice for no obvious reasons: I mean obvious
> from the programmer convenience point of view.
The need for pre-declarations in certain languages has to do with the
way the compilers are implemented. You need at least a two-phase
compiler (that is, a compiler that makes two sweeps over the program or
the intermediate internal representation of the program) to eliminate
the need for forward declarations. However, there are also things like
incremental compilation where it is crucial for the compiler to know the
calling conventions for certain functions that are used in the code to
be compiled but that are not yet defined.
I reckon perl tries to reduce the number of visits of each syntax tree
node as it increases compile-time. Forward-declarations are one way to
ensure that prototypes can be checked at compile-time without the need
of running through the abstract syntax tree too often.
> Anyway, what's the canonical way of including these protos? If I stick all
> of them at the beginning of the file, it is confusing for people reading it
> the first time. But then again I haven't seen people using C-like include
> files for definitions, either, and am unsure as to what extension such files
> should have. ph comes to mind standing for perl header.
Perl headers are already used for something else and they have .ph as
extension. See 'perldoc h2ph'. It's fairly obscure.
Just use .pm as extension which is also the only way that ensures you
can include it with 'use'. If you want to indicate that a module only
consists forward declaration use an appropriate naming scheme:
Module_inc.pm # or Module_fwd.pm or so
Module.pm
Note that the file containing the forward declarations needs to be
included at compile-time in order to have any effect. When you include
modules via 'use', this happens anyway.
> If I want to be truely lazy, is there a way of automatically copying the
> prototype from the implementation and placing it before the function is
> being used? I hope someone else has already done something like this and
> will search using PPM. Source filtering comes to mind as the first choice.
Source filtering is probably the only way as it happens early enough,
namely at scan-time. But it's a heavy and in parts error-prone weapon.
But then I don't entirely understand your issue. If you have functions
in a module then you need to include this module in your programs
anyway. Do it with 'use' and no issues will arise.
Tassilo
--
use bigint;
$n=71423350343770280161397026330337371139054411854220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
.
- Follow-Ups:
- Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- From: Veli-Pekka Tätilä
- Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- References:
- Implementing Interfaces and Type Safety (OOP Newbie in Perl)
- From: Veli-Pekka Tätilä
- Re: Implementing Interfaces and Type Safety (OOP Newbie in Perl)
- From: Tassilo v. Parseval
- Re: Interfaces and Type Safety, Dynamic Typing (OOP Newbie in Perl)
- From: Veli-Pekka Tätilä
- Re: Interfaces and Type Safety, Dynamic Typing (OOP Newbie in Perl)
- From: Tassilo v. Parseval
- Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- From: Veli-Pekka Tätilä
- Implementing Interfaces and Type Safety (OOP Newbie in Perl)
- Prev by Date: Re: Organizing data for readability and efficiency
- Next by Date: How to emulate the Unix command "which"
- Previous by thread: Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- Next by thread: Re: Dynamic Typing, Defencive Programming and Prototypes (Was: Interfaces and Type Safety)
- Index(es):
Relevant Pages
|
Loading