Re: [Zope-dev] Michel's Reply

2000-10-25 Thread Michel Pelletier

Toby Dickenson wrote:
> 

Sorry for the delay (book ... crushing ... head ... )

> Perhaps the hippo analogy isnt helping, so heres a more concrete example. In
> zope today it is possible for a user who has been granted the 'View
> Management Screens' permission in *one* folder to create a one-line dtml
> method that lets him see the management page of any other dtml method in the
> whole site.

Even above where the user is defined?  Are you sure?  That would be a
bug.

Your arguments are all pretty solid, I think we are just looking at
things from different perspectives. 
 
> > > Ive now nearly finished converting all my newbie zope
> > projects back to
> > > a conventional O-O design. I have been bitten by all the problems
> > > listed above. The feed method *should* *be* implemented in
> > a ZooAnimal
> > > base class.
> >
> > Ok, that's a valid approach.
> 
> Can you explain any advantage of the approach you are advocating?

We're working to make Zope usable from the perspective of many
different, possibly non-programming users.  I agree that a feed method
on an animal base class is a good way to do it from the perspective of
an python OO programmer (which you and I are), but people need to be
able to pick up, say, our book, and start creating useful dynamic
content by dropping in objects, scripts, HTML and other stuff they can
grok.  

I agree that this can also be a hinderance, I did some training in
california a few months ago and the company was doing all of their
application in DTML and external Methods and I convinced them (rather
easily because they were all coders) to make a Python product instead.  

Zope's audience can be pictured, like many things, as a bell curve. 
We're (most of us at least) all sittin' up on the top of the hump
looking down.  Understanding the perspective of someone at the bottom
looking up is essential to making sure Zope succeeds.

Python Methods are a perfect example of an object that is useful to us
at the top for advanced things, like methods of a animal base class we
use in our complex Zoo application, but they are also just as useful to
those at the bottom, as a simple little script written in python that
feeds the hippos.  Or unobfusicates their DTML.  Or iterates over a
database query.  It's useful and saves the time of these novice Zope
users if these methods can be flexible and reusable in different
contexts.  To me, this is the heart of the container vs. context binding
argument.  We at the top ususaly want the container because we're
engineering methods on classes.  Those at the bottom usually want
context for entirely different reasons.  Evan has done a great job
making an object that satisfies the entire spectrum, but in the process
has come up with something that is not entirely unlike a method in
python.

I'm not longer arguing or advocating a particular stance on container
vs. context, Evan talked me into the legitimacy of both approaches. 
Right now, I'm arguing that we need a name that makes sense to
everybody.  'Method' makes sense to us at the top, but not to those on
the bottom, and there are a lot more of those people than us.

-Michel

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




RE: [Zope-dev] Michel's Reply

2000-10-23 Thread Toby Dickenson

> I'm not sure I grok what rightness has to do about it.  I 
> think this is
> right, to me wrong == broken.  This is not broken.

Let me persuade you.

> > * someone adds an property named feed to an object at an 
> intermediate
> > location in the containment heirarchy. This breaks the cron job that
> > calls self.Zoo.Diet.LargeAnimals.hippo.feed(), and all the hippos
> > starve.
> 
> This is the classic anti-acquisition argument, but it's a red 
> herring. 

I used to believe that too, but no longer agree. I changed my mind after
developing a large application in Zope, and spending alot of time
firefighting the problems that it caused.

> The same argument applies to inheritance; introducing an attribute
> between two classes in a generalized relationship and your app breaks
> and all the hippos starve anyway.

This analogy is false. If a programmer is responsible for a class and it
becomes broken in that way then yes, he is at fault. Fortunately there are
well understood principles for design inheritance relationships to keep this
easy. Each project has a finite number of classes. Each class has
dependencies to only a small number of other classes. Testing (is used
appropriately) can be used to ensure correctness, and this probably means
re-testing each derived class when a base class changes.

The same is not true of a containment heirarchy.

The containment heirarchy is managed by content managers, who are
responsible for content. After adding content they might test that content,
but they are unlikely to retest any functionality - its not their
responsibility.

The containment heirarchy is often large and sprawling. Acquisition-based
bugs occur on a per-instance basis, not per-class, and typically there will
be very many more instances in a system than there are classes. After a
change to an instance there is a need to re-test *every* *instance* below
the change in the containment heirachy. (When was the last time you changed
your root folder? Did you test your whole site?). This makes it impractical
to test them all.



You raised the question of whether this is an anti-acquisition argument or a
containtment-vs-context-binding argument. Please dont misunderstand me;
acquisition is great when used appropriately. However if methods bound to
containement then acquisition could not be used for the purpose you are
demonstrating here.



>  Zope cannot be robust against
> programmer error.  Nothing can.

I, as a programmer, develop Zope products. My users install them on their
system.

If your users are programmers then this comment is relevant, but I dont.

Adding a property to an object (using the Property tab in the management
interface) is a user-level operation. I do expect my systems to be robust
against user error.

(Note that it is even possible to 'break' Zope's own management interface by
adding some carefully named properties. Some of those are even WikiNames ;-)


> > * someone uses self.Zoo.Diet.buildings.visitor_reception.feed(), and
> > ends up filling the reception with hippo food. (This might even be
> > possible for someone who has no permissions on the reception object)
> 
> This is once again programmer error.

Do you mean the programmer who implemented 'feed'? If yes, Im pleased you
agree with me. Their mistake was to use acquisition instead of inheritance.
If they wanted to use acquistion then they would need to augment their
otherwise simple implementation of 'feed' with either:
1. Explicit security checks (hard to get right)
2. Explicit is_instance checks (inflexible)
3. Accept the fact that anyone granted the 'Feed Hippos' permission on any
hippo may dump hippo feed anywhere, or feed other hippos for which they do
not have that permission.

Perhaps the hippo analogy isnt helping, so heres a more concrete example. In
zope today it is possible for a user who has been granted the 'View
Management Screens' permission in *one* folder to create a one-line dtml
method that lets him see the management page of any other dtml method in the
whole site.

Why? because DTMLMethod's manage_main binds to context not containment.


> > * someone uses
> > 
> self.Zoo.buildings.office.printers.laserjet1.Zoo.Diet.LargeAni
> mals.hippo.feed(),
> > and ends up feeding paper to the hippo. (that could even be someone
> > who has no other permisions on that hippo object)
> 
> This is the same as your first two arguments: programmer error.

(Note: Michel is right that this one is not immediately relevant
  to the binding discussion; its purely a demonstration of a
  misuse of acquisition. Its also a programmer error, but in
  Michel is that programmer)

The real problem here is that you are relying on acquisition from a context
that is not a direct container. Each instance only has one containment
heirarchy. However it has an infinite number of possible contexts, which are
chosen by the caller.

Suppose you have an (apparently correct) external method in Zoo:

def feeding_time(self):

Re: [Zope-dev] Michel's Reply

2000-10-20 Thread Michel Pelletier

Toby Dickenson wrote:
> 
> On Fri, 20 Oct 2000 12:54:19 +0100, Chris Withers <[EMAIL PROTECTED]>
> wrote:
> 
> >>Consider the following passage in the documentation:
> 
> Noo - Context-based instance-space applications are a major source
> of pain, bugs and security holes. They might be the one thing that
> Zope does different (and therefore they need to be explained) but that
> doesnt make them right.

I'm not sure I grok what rightness has to do about it.  I think this is
right, to me wrong == broken.  This is not broken.
 
> 
> Thats fine until:
> 
> * someone adds an property named feed to an object at an intermediate
> location in the containment heirarchy. This breaks the cron job that
> calls self.Zoo.Diet.LargeAnimals.hippo.feed(), and all the hippos
> starve.

This is the classic anti-acquisition argument, but it's a red herring. 
The same argument applies to inheritance; introducing an attribute
between two classes in a generalized relationship and your app breaks
and all the hippos starve anyway.  Zope cannot be robust against
programmer error.  Nothing can.
 
> * someone uses self.Zoo.Diet.buildings.visitor_reception.feed(), and
> ends up filling the reception with hippo food. (This might even be
> possible for someone who has no permissions on the reception object)

This is once again programmer error.
 
> * someone wants to have a dinner party; feeding more than one animal
> at once. But then he finds he has to switch to a different technique
> because he cant call his dinner_party() method with more than one
> context at the same time.

Can you explain this some more?  I'm a bit lost on how this invalidates
context vs. containment when binding methods.  You're right, you can't
have more than one context at a time, but neiter can you be bound to
more than one container.  If you want to feed more than one animal, use
a loop and iterate over them.

> * someone uses
> self.Zoo.buildings.office.printers.laserjet1.Zoo.Diet.LargeAnimals.hippo.feed(),
> and ends up feeding paper to the hippo. (that could even be someone
> who has no other permisions on that hippo object)

This is the same as your first two arguments: programmer error.
 
> Ive now nearly finished converting all my newbie zope projects back to
> a conventional O-O design. I have been bitten by all the problems
> listed above. The feed method *should* *be* implemented in a ZooAnimal
> base class.

Ok, that's a valid approach.

-Michel

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )




Re: [Zope-dev] Michel's Reply

2000-10-20 Thread Toby Dickenson

On Fri, 20 Oct 2000 12:54:19 +0100, Chris Withers <[EMAIL PROTECTED]>
wrote:

>>Consider the following passage in the documentation:

Noo - Context-based instance-space applications are a major source
of pain, bugs and security holes. They might be the one thing that
Zope does different (and therefore they need to be explained) but that
doesnt make them right.

>> Suppose 'feedHippo.py' is a Python Method. How could you call the
>> 'Diet/feed' method on the 'LargAnimals/Hippo' object from your
>> Python Method. Here's how::
>>
>>   self.Zoo.Diet.LargeAnimals.hippo.feed()
>>
>> In other words you simply access the object using the same
>> acquisition path as you would use if calling it from the
>> web. Likewise in Perl you could say::
>>
>>   $self.Zoo.Diet.LargAnimals.hippo->feed();
>>
>> Using methods from other methods is very similar to calling
>> methods from the web. The semantics differ slightly but the same
>> acquisition rules apply.

Thats fine until:

* someone adds an property named feed to an object at an intermediate
location in the containment heirarchy. This breaks the cron job that
calls self.Zoo.Diet.LargeAnimals.hippo.feed(), and all the hippos
starve.

* someone uses self.Zoo.Diet.buildings.visitor_reception.feed(), and
ends up filling the reception with hippo food. (This might even be
possible for someone who has no permissions on the reception object)

* someone wants to have a dinner party; feeding more than one animal
at once. But then he finds he has to switch to a different technique
because he cant call his dinner_party() method with more than one
context at the same time.

* someone uses
self.Zoo.buildings.office.printers.laserjet1.Zoo.Diet.LargeAnimals.hippo.feed(),
and ends up feeding paper to the hippo. (that could even be someone
who has no other permisions on that hippo object)



Ive now nearly finished converting all my newbie zope projects back to
a conventional O-O design. I have been bitten by all the problems
listed above. The feed method *should* *be* implemented in a ZooAnimal
base class.



Toby Dickenson
[EMAIL PROTECTED]

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )