Object Oriented programs, Perl and others

M

Matthew Braid

Hi all,

I've been spending a lot of time lately writing a lot of objects for a project
here (so far about 60 objects and counting), and while I've been considering
security the whole way I've started thinking one level down on how to secure
objects from direct alteration if they were used as a library in some other
code. (At the moment this isn't _really_ an issue as the packages are not
available to users unless they go through controlled programs that don't allow
unknown code to run).

After tinkering, I've come up with the following pseudo-rules (please correct me
if I'm wrong here, and preferably give me pointers :)

1. If an object inherits from another object (in perl), it is free to
change/override any sub inside the parent.

2. There is no way to stop code from altering a class directly (eg, by doing
something like 'sub Object::_internal { something_unexpected() }'

3. The fixes I've so far run across (my'd hashes keyed on blessed references to
store instance data instead of using hashes for the base instance structure,
my'd subroutines for truly private methods) work (well, as far as they can
considering 1 and 2) but make inheritance an absolute nightmare - children can't
get hold of parent's protected data. Writing accessor methods for them is
problematic because of 2 - the accessor can be replaced to return something else.

4. Even if perl strictly adhered to OO paradigms I've learnt, some of these
problems are very hard to fix.

I've been thinking of theoretical ways to fix problems like this, and my
amateurish ideas so far have been:

1. Closing packages - from then on, no other code can enter that package's
namespace to specify subs, ie this:

package Example is closed; # Made up syntax - maybe should be fatal if the
# Example namespace already exists
our($Bar) = '123';
sub foo { ... }

package main;
sub Example::foo { ... } # Fatal - modify closed package
sub Example::eek:ther { ... } # Fatal - add to closed package
$Example::Bar = '321'; # OK - not changing a sub

package OtherExample;
use base qw/Example/;

sub foo { ... } # OK - this is an override, doesn't
# alter the Example package

This could be expanded to making packages 'append only' (only new subs added) as
well etc etc.

2. Closing subs - from then on, child packages and external code cannot override
a particular sub:

package Example;

sub foo is closed { ... } # More made up syntax. Maybe a warning if
# Example::foo is already defined
sub bar { ... }

package OtherExample;
use base qw/Example/;
sub foo { ... } # Fatal - the sub is closed and cannot be
# overriden, even by children
sub bar { ... } # OK

package main;
sub Example::foo { ... } # Fatal - same reason as above

3. 'Closed Object Families' or 'Willed Inheritance'. This one breaks the idea
that a parent need not know anything about its children a bit, but it limits who
can inherit from it:

package Example wills qw(OtherExample # Made up syntax - 'wills'
MoreExamples); # as in 'I hereby will my
# stuff to the following
# children...'
....

package MoreExamples;
use base qw/Example/; # OK - this is one of our 'trusted' children
....

package UnexpectedExample;
use base qw/Example/; # Fatal - not one of our trusted children, not allowed
# to inherit.

Using mixes of these, you can start to be confident to write accessors for
objects for finding out if they can do something potentially dangerous, or for
accessors to find out parameters for potentially dangerous actions, eg:

package Example is closed, wills qw(OtherExample);
my %Private;
sub new {
my $class = shift;
my $self = bless('', $class); # short version :)
$Private{$self} = {CanDelete => 0,
ID => 'someid'};
return $self;
}
sub can_delete is closed {
my $self = shift;
return 0 if not exists $Private{$self}; # Safe default
return $Private{$self}{CanDelete};
}
sub do_delete {
my $self = shift;
return 0 if not $self->can_delete;
# Do the delete...
return 1;
}

Now instances of Example and OtherExample can safely assume that:

$eg->can_delete

hasn't been overridden like:

sub Example::can_delete { return 1 }

(and do_delete hasn't been modified by 'untrusted' code), so can be used in
arbitrary code as library code (...I think :) )

This is all just musings off the top of my head - for all I know perl has some
of this already that I don't know about, and I haven't descended to the level
below (how can I be sure the user loaded the right module and not something from
a private directory etc), _and_ nothing here defines what happens if a package
tries to inherit from a package that has inherited from a _willed_ package (sheesh!)

All up I think I've been thinking too much about this stuff anyway :)

MB
 
U

Uri Guttman

wait for perl6. it will have all that you ask for and more. perl5 won't
ever have it but you can use modules that do support some of those
ideas. also get the book 'object oriented perl' by damian conway. it
will teach you all you need to know about OO perl.

uri
 
D

Daniel Berger

Matthew Braid said:
Hi all,

I've been spending a lot of time lately writing a lot of objects for a project
here (so far about 60 objects and counting), and while I've been considering
security the whole way I've started thinking one level down on how to secure
objects from direct alteration if they were used as a library in some other
code. (At the moment this isn't _really_ an issue as the packages are not
available to users unless they go through controlled programs that don't allow
unknown code to run).

After tinkering, I've come up with the following pseudo-rules (please correct me
if I'm wrong here, and preferably give me pointers :)

1. If an object inherits from another object (in perl), it is free to
change/override any sub inside the parent.

2. There is no way to stop code from altering a class directly (eg, by doing
something like 'sub Object::_internal { something_unexpected() }'

3. The fixes I've so far run across (my'd hashes keyed on blessed references to
store instance data instead of using hashes for the base instance structure,
my'd subroutines for truly private methods) work (well, as far as they can
considering 1 and 2) but make inheritance an absolute nightmare - children can't
get hold of parent's protected data. Writing accessor methods for them is
problematic because of 2 - the accessor can be replaced to return something else.

4. Even if perl strictly adhered to OO paradigms I've learnt, some of these
problems are very hard to fix.

I've been thinking of theoretical ways to fix problems like this, and my
amateurish ideas so far have been:

1. Closing packages - from then on, no other code can enter that package's
namespace to specify subs, ie this:

package Example is closed; # Made up syntax - maybe should be fatal if the
# Example namespace already exists
our($Bar) = '123';
sub foo { ... }

package main;
sub Example::foo { ... } # Fatal - modify closed package
sub Example::eek:ther { ... } # Fatal - add to closed package
$Example::Bar = '321'; # OK - not changing a sub

package OtherExample;
use base qw/Example/;

sub foo { ... } # OK - this is an override, doesn't
# alter the Example package

This could be expanded to making packages 'append only' (only new subs added) as
well etc etc.

2. Closing subs - from then on, child packages and external code cannot override
a particular sub:

package Example;

sub foo is closed { ... } # More made up syntax. Maybe a warning if
# Example::foo is already defined
sub bar { ... }

package OtherExample;
use base qw/Example/;
sub foo { ... } # Fatal - the sub is closed and cannot be
# overriden, even by children
sub bar { ... } # OK

package main;
sub Example::foo { ... } # Fatal - same reason as above

3. 'Closed Object Families' or 'Willed Inheritance'. This one breaks the idea
that a parent need not know anything about its children a bit, but it limits who
can inherit from it:

package Example wills qw(OtherExample # Made up syntax - 'wills'
MoreExamples); # as in 'I hereby will my
# stuff to the following
# children...'
....

package MoreExamples;
use base qw/Example/; # OK - this is one of our 'trusted' children
....

package UnexpectedExample;
use base qw/Example/; # Fatal - not one of our trusted children, not allowed
# to inherit.

Using mixes of these, you can start to be confident to write accessors for
objects for finding out if they can do something potentially dangerous, or for
accessors to find out parameters for potentially dangerous actions, eg:

package Example is closed, wills qw(OtherExample);
my %Private;
sub new {
my $class = shift;
my $self = bless('', $class); # short version :)
$Private{$self} = {CanDelete => 0,
ID => 'someid'};
return $self;
}
sub can_delete is closed {
my $self = shift;
return 0 if not exists $Private{$self}; # Safe default
return $Private{$self}{CanDelete};
}
sub do_delete {
my $self = shift;
return 0 if not $self->can_delete;
# Do the delete...
return 1;
}

Now instances of Example and OtherExample can safely assume that:

$eg->can_delete

hasn't been overridden like:

sub Example::can_delete { return 1 }

(and do_delete hasn't been modified by 'untrusted' code), so can be used in
arbitrary code as library code (...I think :) )

This is all just musings off the top of my head - for all I know perl has some
of this already that I don't know about, and I haven't descended to the level
below (how can I be sure the user loaded the right module and not something from
a private directory etc), _and_ nothing here defines what happens if a package
tries to inherit from a package that has inherited from a _willed_ package (sheesh!)

All up I think I've been thinking too much about this stuff anyway :)

MB

If you want an OO scripting language *today* consider Ruby or Python.
Lord only knows when Perl6 will be out.

Regards,

Dan
 
U

Uri Guttman

DB> If you want an OO scripting language *today* consider Ruby or Python.
DB> Lord only knows when Perl6 will be out.

and you had to quote the entire post just for your 2 lines of specious
wisdom?

uri
 
A

Anno Siegel

Matthew Braid said:
Hi all,

I've been spending a lot of time lately writing a lot of objects for a project
here (so far about 60 objects and counting), and while I've been considering
security the whole way I've started thinking one level down on how to secure
objects from direct alteration if they were used as a library in some other
code. (At the moment this isn't _really_ an issue as the packages are not
available to users unless they go through controlled programs that don't allow
unknown code to run).

After tinkering, I've come up with the following pseudo-rules (please
correct me
if I'm wrong here, and preferably give me pointers :)

1. If an object inherits from another object (in perl), it is free to
change/override any sub inside the parent.

[lots snipped]

Your terminology is slightly off. It's classes that inherit from
one another. Saying that an object inherits something is common,
but nothing but a manner of speech. Saying that an object inherits
from another object is wrong.

On a more general note, I believe it's futile to look for general
solutions for Perl's defects it its support of OO techniques, such as
failure to enforce privacy on classes and objects. It has been noted
that Perl 6 will be fully OO and it will certainly solve these issues.

Singular solutions for one or more of these problems that are applicable
in this or that situation are still of interest. Damian's _Object
Oriented Perl_ holds quite a few of those, and more are available
among the Class::* modules. The web site http://perldesignpatterns.com
seems to be another relevant source, but I haven't seen enough of it
to have an opinion.

Anno
 
M

Matthew Braid

Uri said:
wait for perl6. it will have all that you ask for and more. perl5 won't
ever have it but you can use modules that do support some of those
ideas. also get the book 'object oriented perl' by damian conway. it
will teach you all you need to know about OO perl.

uri

I'm kind of surprised perl6 will have all of that - I thought closing classes
was against the whole perl 'thing' :)

I'm beginning to get a little worried about perl6 - from what I've seen on its
development it seems to be more and more driven on "hey, wouldn't it be cool if
we could do this" or "look, I've defined yet another way to do X" and less and
less on "this is a concise, non-ambiguous way of doing X". Hopefully I've just
been looking in the wrong place.

MB
 
M

Matthew Braid

Anno said:
Your terminology is slightly off. It's classes that inherit from
one another. Saying that an object inherits something is common,
but nothing but a manner of speech. Saying that an object inherits
from another object is wrong.

You're right - sorry, I was writing that a little too fast to double check my
terminology.
On a more general note, I believe it's futile to look for general
solutions for Perl's defects it its support of OO techniques, such as
failure to enforce privacy on classes and objects. It has been noted
that Perl 6 will be fully OO and it will certainly solve these issues.

I thought as much. As a side effect of all this thinking about it I've even
started designing a language myself and it turns out its kinda fun. I didn't
realise I was that much of a geek :) Of course, it'll never get off the ground
but it passes the time.
Singular solutions for one or more of these problems that are applicable
in this or that situation are still of interest. Damian's _Object
Oriented Perl_ holds quite a few of those, and more are available
among the Class::* modules. The web site http://perldesignpatterns.com
seems to be another relevant source, but I haven't seen enough of it
to have an opinion.

I'll check into the Class::* modules - I've touched on them briefly in the past
and some of them seemed pretty cool.

MB
 
D

Daniel Berger

I'm beginning to get a little worried about perl6 - from what I've seen on its
development it seems to be more and more driven on "hey, wouldn't it be cool if
we could do this" or "look, I've defined yet another way to do X" and less and
less on "this is a concise, non-ambiguous way of doing X". Hopefully I've just
been looking in the wrong place.

MB

No, you haven't been looking in the wrong place - you're spot on.
This is why I recommended at least considering Ruby or Python.

Regards,

Dan
 
T

Tassilo v. Parseval

Also sprach Daniel Berger:
No, you haven't been looking in the wrong place - you're spot on.
This is why I recommended at least considering Ruby or Python.

Do this recommendation once Perl6 has been seen in the wild. Such
statements are of no use today where all we have are those documents
describing the differences.

It's really just a case of contorted perception that everyting will be
new in Perl6. It's just so that no one bothered to list the stuff Perl5
and Perl6 will have in common.

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top