From: Graham B. <gb...@po...> - 2000-08-14 14:35:02
|
On Mon, Aug 14, 2000 at 02:45:44PM +0100, John Berthels wrote: > > > > This leads me to think that a high level interface might be useful. Here > > > are a couple of suggestions on how this might differ from Net::LDAP. > > > > > > 1) The ->new method takes an optional username/password and does a > > > Net::LDAP->new and a ->bind. Returns object or under if anything fails. > > > > IMO, this is bad. I even want to move the connect out of new and into a > > separate method so that errors can be returned with more ease. > > I agree that it would be bad for the Net::LDAP API. > > However, for an 'easy to use' interface (Net::LDAP::For::Dummies) I just > want a handle for a connection I can do things with. If the API fails to > create it (for any reason) then fine, return undef and put some > descriptive text in $! but don't make me do 2 or 3 calls to get the > handle. In the common case it will 'just work'. I am all for having some way for Net::LDAP to have "common use" functions. But having a separate API "for dummies" no. > > > i.e. you could write: > > > > > > #!/usr/bin/perl -w > > > use Net::LDAP::Cooked; # or whatever > > > > > > my $l = Net::LDAP::Cooked->new( "local.ldap.server" ) > > > or die( "Can't connect : $!" ); > > > my @staff = $l->list( "ou=staff, o=myorg" ) > > > or die( "Can't list staff : $!" ); > > > > I think this is coming back to having someway, other than inheritance (maybe) > > to extend Net::LDAP. > > Yes. Exactly. I suspect that lots of people writing apps using Net::LDAP > have similar code in their apps. I want to pull that similar code into a > companion module for Net::LDAP for standard code reuse reasons. Right, then lets define a way to do that. > > > foreach my $person( @staff ) { > > > my $name = $person->get( "cn" ); > > > my $phone = $person->get( "telephoneNumber" ); > > > > For the ::Entry I would prefer to keep one module and have it work as > > expected. > > Again - expected by who? A perl programmer. > It may be possible to define an ::Entry API which > satisfies both camps, but if not then why not have two? The 'hard core' > users don't have the impact of the additional fluff and the 'just want it > to work' users don't have to go through additional levels of indirection > to get to their data. I don't think the two camps are that different in terms of 'understandability' just in what level they want access to. > > And I think the above it the "expected" behaviour. Which would mean > > that get returns a list and we add exists. Then we split out the > > extra option code I added into another method, say get_nooptions > > which always returns a hashref > > Something like this would be fine. The only negatives for this would be > bloating the module and which camp was annoyed by having to use the longer > name :-) It would not be bloat as all of it is there now. It just seems the API is hard for some to understand. I belive we should be able to get a single API ot ::Entry that is both powerful enough for the hard core user and simple enough for the beginner. > > > The kinds of things going on here would be: > > > > > > - additional methods which reduce the need to construct arguments to > > > ->search. e.g. ->list, ->read, ->exists > > > > What are ->read and ->exist and called on what object ? > > my $entry = $ldap->read( $dn ); # Call search with scope 0 and filter > > ->exists( $dn ) is true if the entry is in the Directory. At first sight > seems the same as ->read( $dn ) but could be more efficient since it need > not pull back all attributes. Both are syntactic sugar around ->search(). > > The previous discussions around $ldap->alive() (or $ldap->ping()) fit > right in here too. Syntactic sugar. This is perl after all :-) Right. We need a way to add extensions. This can be done in many ways. 1) Inheritance 2) MI 3) allowing others to import into Net::LDAP with a register module. > > > - avoid Net::LDAP::Message returns, give back arrays of > > > Net::LDAP::Cooked::Entry > > > > I would rather just keep one Entry object. > > Fair enough, but see above regarding two audiences. I think we can keep both happy. > > > So, is this something which would be useful to people (or would have been > > > useful to them when starting with Net::LDAP) or does it just hide too much > > > from the user and is likely to confuse them? > > > > Confusion is one thing that concerns me. Because you teach them one > > theng then they have to learn something else if they want to go > > beyond its boundaries. I would prefer to make the API as natural/easy > > as possible. > > This is a very good point. The documentation of all this would have to be > done very carefully. To some extent I think that this might be alleviated > by having the two APIs appear less related. "Oh...you're using > Net::LDAP::Simple. Thats OK, but to do *that* you need to read up on > Net::LDAP". Two documents, yes. Two APIs, I would rather not. We could just make these methods avaliable via the AUTOLOADer or have the user type use Net::LDAP::Extn qw(:simple); to get Net::LDAP::Extn to import some subs into Net::LDAP or just have Net::LDAP::Simple inherit from Net::LDAP and provide these subs. But some of these may be of use to 'hard core' users too, which is why I don't really like the ::Simple appraoch as we will see more and more ::Simple being the main API. > This is why I was thinking inheritance might be bad, since it might appear > to mix the two. Yes. > > > If this is something worth doing, should we add bloat to Net::LDAP to > > > support things like this or should we create a wrapper module. > > > > bloat is something I want to avoid if possible. > > This is the main reason I was thinking about a second API, rather than > trying to make one API all things to all people. > > > > If we create a wrapper module should it live within the Net::LDAP > > > namespace or somewhere else? > > > > probably within. > > Agreed. (But its your namespace :-) But my preference is a way to provide extensions to Net::LDAP, but still (maybe) via a Net::LDAP method. The other option is to provide subs in Net::LDAP::Util > > > Should it inherit from Net::LDAP and add/override methods or should it be > > > a seperate object? > > > > What would it gain from being a separate module ? I would say it > > should inherit, if we have it at all. I would prefer to get the current > > module "fixed" rather than create another module just to provide a different > > API. > > My real question is whether it is better to extend Net::LDAP to make it > easier for novice users (or those who like convenience) or instead to > recognise that there are different types of users and so implement a new > API to meet a different need. I think Net::LDAP is nice, clean and > precise. I like that. I also find myself replicating wrapper functions > from app to app and wishing that they lived in the distribution. What kind of wrapper functions ? give some examples Well we need to define a way for people to make these things easy. > As I see it, the downsides of extending Net::LDAP are bloat and > conflicting design goals. The downsides of a new API are that it is a > little more work. And the fact you end up with two APIs and people asking questions which to use etc... I am sure it is possible to meet the demands of both camps without creating a completely new API. This email is highlighting more than one issue. Lets break it into parts and see what we can develop 1) Net::LDAP::Entry 2) Extending Net::LDAP with common methods In the case of 1) lets list what we should be able to do with an Entry and what a newbie would probably expect. Then compare that with what an expert would expect/need. It may not be that different. Graham. |