From: Karl-Heinz R. <kar...@co...> - 2000-08-08 12:33:06
|
I just installed the new version. $entry->get(attribute) now gives back a reference to an array and no more the value. $entry->dn gives back the dn . (AIX 4.3 / Perl 5.00503) Has there changed something ? mfg / regards Karl-Heinz Rastofer ------------------------------------------------- ICA GmbH Büttnerstraße 21, Raum 502 D-30165 Hannover 423 - Produktions- und Kompetenz-Team, Communication Services Tel. +49-511-938 - 25691 / Fax - 825691 notes - Karl-Heinz Rastofer/VB/DE/CONTI/DE internet - mailto:kar...@no... |
From: Karl-Heinz R. <kar...@co...> - 2000-08-09 08:32:15
|
just to keep track of changes: Anonymous bind does no more work with my old version (top), but I had to change the code (see below). #------------------------------------------------------------- # sub ldapbind returns ldap-object OLD #------------------------------------------------------------- sub f_ldapbind { my ($cref,$vref) = @_; my ($ldap,$ldap_ref,$msg,$msg_ref,$dn,$uid,$pwd); my %cookie = %$cref; my %v = %$vref; $uid = $cookie{$v{'authuid'}} || ""; $pwd = $cookie{$v{'authpwd'}} || ""; $dn = "uid=" . $uid . "," . $cookie{$v{'base'}}; $ldap = new Net::LDAP($cookie{$v{'servername'}}, port=>$cookie{$v{'serverport'}} ); $msg = $ldap->bind( $dn , password => $pwd, version => 3 ); $ldap_ref = \$ldap; $msg_ref = \$msg; return ($msg_ref, $ldap_ref); } #-------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------- # sub ldapbind returns ldap-object NEW #------------------------------------------------------------- sub f_ldapbind { my ($cref,$vref) = @_; my ($ldap,$ldap_ref,$msg,$msg_ref,$dn,$uid,$pwd); my %cookie = %$cref; my %v = %$vref; $uid = $cookie{$v{'authuid'}} || ""; $pwd = $cookie{$v{'authpwd'}} || ""; $dn = "uid=" . $uid . "," . $cookie{$v{'base'}}; $ldap = new Net::LDAP($cookie{$v{'servername'}}, port=>$cookie{$v{'serverport'}}); if ($uid and $pwd) { $msg = $ldap->bind( $dn , password => $pwd, version => 3 ); } else { $msg = $ldap->bind; } $ldap_ref = \$ldap; $msg_ref = \$msg; return ($msg_ref, $ldap_ref); } |
From: Graham B. <gb...@po...> - 2000-08-09 09:05:26
|
This is a change that was forgotten in the RELEASE_NOTES, sorry. You must now be explicit about anonymous binds. Either $ldap->bind; or if you specify any arguments, you must use 'noauth' or 'anonymous' instead of 'password' (the value is ignored) e.g. $ldap->bind($dn, noauth => 1, version => 3); or $ldap->bind( anonymous => 1, version => 3); 'password' with an empty argument will fail with LDAP_INAPPROPRIATE_AUTH Although when we get protocol vs local errors separated, what it fails with may change. This is to prevent an anonymous bind happening by accident. Graham. On Wed, Aug 09, 2000 at 10:31:39AM +0200, Karl-Heinz Rastofer wrote: > just to keep track of changes: > > Anonymous bind does no more work with my old version (top), but I had to change > the > code (see below). > > #------------------------------------------------------------- > # sub ldapbind returns ldap-object OLD > #------------------------------------------------------------- > sub f_ldapbind { > my ($cref,$vref) = @_; > my ($ldap,$ldap_ref,$msg,$msg_ref,$dn,$uid,$pwd); > my %cookie = %$cref; > my %v = %$vref; > $uid = $cookie{$v{'authuid'}} || ""; > $pwd = $cookie{$v{'authpwd'}} || ""; > $dn = "uid=" . $uid . "," . $cookie{$v{'base'}}; > > $ldap = new Net::LDAP($cookie{$v{'servername'}}, port=>$cookie{$v{'serverport'}} > ); > $msg = $ldap->bind( $dn , > password => $pwd, > version => 3 ); > $ldap_ref = \$ldap; > $msg_ref = \$msg; > > return ($msg_ref, $ldap_ref); > } > #-------------------------------------------------------------------------------------------------------------------- > > #------------------------------------------------------------- > # sub ldapbind returns ldap-object NEW > #------------------------------------------------------------- > sub f_ldapbind { > my ($cref,$vref) = @_; > my ($ldap,$ldap_ref,$msg,$msg_ref,$dn,$uid,$pwd); > my %cookie = %$cref; > my %v = %$vref; > $uid = $cookie{$v{'authuid'}} || ""; > $pwd = $cookie{$v{'authpwd'}} || ""; > $dn = "uid=" . $uid . "," . $cookie{$v{'base'}}; > > $ldap = new Net::LDAP($cookie{$v{'servername'}}, > port=>$cookie{$v{'serverport'}}); > > if ($uid and $pwd) { > $msg = $ldap->bind( $dn , > password => $pwd, > version => 3 ); > } else { > $msg = $ldap->bind; > } > $ldap_ref = \$ldap; > $msg_ref = \$msg; > > return ($msg_ref, $ldap_ref); > } > > > |
From: Graham B. <gb...@po...> - 2000-08-08 13:13:39
|
On Tue, Aug 08, 2000 at 02:32:24PM +0200, Karl-Heinz Rastofer wrote: > I just installed the new version. > > $entry->get(attribute) now gives back a reference to an array and no more the > value. > $entry->dn gives back the dn . > > (AIX 4.3 / Perl 5.00503) > > Has there changed something ? Yes, I was waiting for someone to report that, and I am surprised it took so long. The RELEASE_NOTES do state * Net::LDAP::Entry->get now always returns a scalar result as documented. The fact is ->get was never documented to return list, only a reference to a list. In 0.20 you can now ask for all options to an attribute so $entry->get('cn', alloptions => 1); will return a hash reference which may look like { 'en' => "value for cn;en", 'fr' => "value for cn;fr" }; It was in adding this I noticed the list return for get. The problem with the list return is that if an attribute exists, but is empty you cannot tell because you get the empty list, just like you do if the attribute does not exist. However I can see how people might like the list return so for single valued entries you get my $cn = $entry->get('cn'); as opposed to my $cn = $entry->get('cn')->[0]; I am open to suggestions. The only thing I can think of is to revert to what was there, allow the hash return in a list context too and add and exists method to check if an attribute exists. Comments. Graham. |
From: John B. <joh...@ne...> - 2000-08-14 10:26:55
|
[snip get now returns array ref or hash ref] > I am open to suggestions. The only thing I can think of is to revert to > what was there, allow the hash return in a list context too and add and > exists method to check if an attribute exists. > > Comments. I get the feeling (perhaps wrongly) that users of Net::LDAP divide up into two camps. Those that want/require the level of control which the protocol provides (access to all options, methods mapping onto single operations, etc) and those that just want to push and pull data from an LDAP server in the simplest way possible. Additionally, the same person might place themselves in either camp depending on the task at hand. 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. 2) In general, methods return true on success, undef or () on failure Yes, this means you can't tell the difference between 'no data' or 'error'. If the user doesn't care that's fine (since they may need to handle 'no data' as an application error anyway). Otherwise we could set $! (or $@?) and/or provide a 'did an error happen' function. 3) Object destructor does an unbind and closes the socket. (Not sure if Net::LDAP does this already...probably) 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 : $!" ); foreach my $person( @staff ) { my $name = $person->get( "cn" ); my $phone = $person->get( "telephoneNumber" ); print "$name\t$phone\n"; } 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 - avoid Net::LDAP::Message returns, give back arrays of Net::LDAP::Cooked::Entry - The 'cooked' entries support simple retrieval of scalars. If attr is multi-valued simply give back first. Provide ->get_all() get an array of all values back. 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? 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. If we create a wrapper module should it live within the Net::LDAP namespace or somewhere else? Should it inherit from Net::LDAP and add/override methods or should it be a seperate object? regards, jb |
From: Graham B. <gb...@po...> - 2000-08-14 11:08:28
|
On Mon, Aug 14, 2000 at 11:26:25AM +0100, John Berthels wrote: > > [snip get now returns array ref or hash ref] > > > I am open to suggestions. The only thing I can think of is to revert to > > what was there, allow the hash return in a list context too and add and > > exists method to check if an attribute exists. > > > > Comments. > > I get the feeling (perhaps wrongly) that users of Net::LDAP divide up into > two camps. Those that want/require the level of control which the protocol > provides (access to all options, methods mapping onto single operations, > etc) and those that just want to push and pull data from an LDAP server in > the simplest way possible. Additionally, the same person might place > themselves in either camp depending on the task at hand. True. > 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. > 2) In general, methods return true on success, undef or () on failure Yes, > this means you can't tell the difference between 'no data' or 'error'. If > the user doesn't care that's fine (since they may need to handle 'no data' > as an application error anyway). Otherwise we could set $! (or $@?) and/or > provide a 'did an error happen' function. I can see why some people may want this. But I am not sure I like it too much. > 3) Object destructor does an unbind and closes the socket. (Not sure if > Net::LDAP does this already...probably) No it does not. And I am not sure about the unbind, I have had bad experiences with other modules doing quit on DESTROY. An perl will close the socket anyway. > 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. > 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. 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 > 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 ? > - avoid Net::LDAP::Message returns, give back arrays of > Net::LDAP::Cooked::Entry I would rather just keep one Entry object. > - The 'cooked' entries support simple retrieval of scalars. If attr is > multi-valued simply give back first. Provide ->get_all() get an array of > all values back. I would prefer to just make get context sensetive. > 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. > 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. > If we create a wrapper module should it live within the Net::LDAP > namespace or somewhere else? probably within. > 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. Graham. |
From: John B. <joh...@ne...> - 2000-08-14 13:51:55
|
> > 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'. > > 2) In general, methods return true on success, undef or () on failure Yes, > > this means you can't tell the difference between 'no data' or 'error'. If > > the user doesn't care that's fine (since they may need to handle 'no data' > > as an application error anyway). Otherwise we could set $! (or $@?) and/or > > provide a 'did an error happen' function. > > I can see why some people may want this. But I am not sure I like it > too much. It should be OK for any app which wants to attempt to get data and can throw an error if it can't get it. If the app is implementing recovery then the user is 'sophisticated' and can use straight 'Net::LDAP'. > > 3) Object destructor does an unbind and closes the socket. (Not sure if > > Net::LDAP does this already...probably) > > No it does not. And I am not sure about the unbind, I have had bad experiences > with other modules doing quit on DESTROY. An perl will close the socket > anyway. Fair enough. > > 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. > > 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? 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. > 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 :-) > > 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 :-) > > - 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. > > - The 'cooked' entries support simple retrieval of scalars. If attr is > > multi-valued simply give back first. Provide ->get_all() get an array of > > all values back. > > I would prefer to just make get context sensetive. Ditto last comment. > > 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". This is why I was thinking inheritance might be bad, since it might appear to mix the two. > > 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 :-) > > 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. 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. regards, jb |
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. |
From: David B. <d.b...@ma...> - 2000-08-14 22:55:40
|
Bravo everyone, I can't add much more to the debate except to say I'm on the side of everyone that wants to make the Net::LDAP API simpler by default, but more powerful if desired. It seems to me that there are a lot of people out there doing : Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); How's this for another optional feature... my $a = Net::LDAP->new("ldap.server.org",on_error=>die); my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); Obviously, the on_error value would apply to all binds/queries/searches/lists/reads performed using that connection handle. David. At 03:30 PM 8/14/00 +0100, Graham Barr wrote: >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. > > > -------------------------------------------------------------------- David Bussenschutt Email: D.B...@ma... Senior Computing Support Officer & Systems Administrator/Programmer Location: Griffith University. Information Technology Services Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 -------------------------------------------------------------------- |
From: Mark W. <mew...@un...> - 2000-08-15 00:46:00
|
Problem with defining a default on_error is that some errors are expected. For example in compare, the results will either be 5 for false or 6 for true (or is it vice/versa ?) mark David Bussenschutt wrote: > Bravo everyone, > > I can't add much more to the debate except to say I'm on the side of > everyone that wants to make the Net::LDAP API simpler by default, but more > powerful if desired. > > It seems to me that there are a lot of people out there doing : > Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); > > How's this for another optional feature... > > my $a = Net::LDAP->new("ldap.server.org",on_error=>die); > my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); > my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); > my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); > > Obviously, the on_error value would apply to all > binds/queries/searches/lists/reads performed > using that connection handle. > > David. > > At 03:30 PM 8/14/00 +0100, Graham Barr wrote: > >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. > > > > > > > > -------------------------------------------------------------------- > David Bussenschutt Email: D.B...@ma... > Senior Computing Support Officer & Systems Administrator/Programmer > Location: Griffith University. Information Technology Services > Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 > -------------------------------------------------------------------- |
From: David B. <d.b...@ma...> - 2000-08-15 03:46:17
|
Hi again, Why not handle the 'expected'? When using this hypothetical "on_error", if the operation has an obvious "operation failed" return, then die/croak/\&callback/whatever and If the operation has return codes that don't meet that criteria, then don't. Eg, 'compare', should really consider both a true and a false return value as being valid "operation successful"... since to get either of those values then compare had to succeed in the compare. What happens when compare has (for example) an internal error and/or the data was uncomparable for unknown reason? Is this handled at the moment? It should in my opinion be this is what could/should cause an on_error event in compare's case. And for that matter, by allowing a user-defined subroutine as an on_error, you could allow the user(programmer) to define a callback for 'compare' that dies/croaks/whatever whenever the user(programmer) desires (including error code 5 or 6). By doing this the API is simpler, the bloat is negligable, the users are happier, the resultant code is easier to read... what more could you want? I mean, the "|| die.." code will be written anyway so in the module is a better place for it, so it doesn't have to be written over and over again! As I understand it, this would also clear-up the problem the API currently has with it's inability to determine if a search returned no results because there was nothing to return or because of an error performing the search. My 2c. What do others think? David. At 07:46 PM 8/14/00 -0500, you wrote: >Problem with defining a default on_error is that some errors are expected. For example in >compare, the results will either be 5 for false or 6 for true (or is it vice/versa ?) > >mark > >David Bussenschutt wrote: > >> Bravo everyone, >> >> I can't add much more to the debate except to say I'm on the side of >> everyone that wants to make the Net::LDAP API simpler by default, but more >> powerful if desired. >> >> It seems to me that there are a lot of people out there doing : >> Net::LDAP->some_op( blah blah ) || die ("some op failed $!"); >> >> How's this for another optional feature... >> >> my $a = Net::LDAP->new("ldap.server.org",on_error=>die); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>croak); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>carp); >> my $a = Net::LDAP->new("ldap.server.org",on_error=>\&myfunction()); >> >> Obviously, the on_error value would apply to all >> binds/queries/searches/lists/reads performed >> using that connection handle. >> >> David. >> >> At 03:30 PM 8/14/00 +0100, Graham Barr wrote: >> >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. >> > >> > >> > >> >> -------------------------------------------------------------------- >> David Bussenschutt Email: D.B...@ma... >> Senior Computing Support Officer & Systems Administrator/Programmer >> Location: Griffith University. Information Technology Services >> Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 >> -------------------------------------------------------------------- > > > > -------------------------------------------------------------------- David Bussenschutt Email: D.B...@ma... Senior Computing Support Officer & Systems Administrator/Programmer Location: Griffith University. Information Technology Services Brisbane Qld. Aust. (TEN bldg. rm 1.33) Ph: (07)38757079 -------------------------------------------------------------------- |
From: Graham B. <gb...@po...> - 2000-08-15 08:43:16
|
On Tue, Aug 15, 2000 at 01:47:07PM +1000, David Bussenschutt wrote: > Hi again, > > Why not handle the 'expected'? What is expected ? > What happens when compare has (for example) an internal error and/or the > data was uncomparable for unknown reason? Is this handled at the moment? > It should in my opinion be this is what could/should cause an on_error > event in compare's case. It returns the error from the server. It is up to the application to determine what to do with that error. > And for that matter, by allowing a user-defined subroutine as an on_error, > you could allow the user(programmer) to define a callback for 'compare' > that dies/croaks/whatever whenever the user(programmer) desires (including > error code 5 or 6). Hm, maybe more thought is needed here. > By doing this the API is simpler, really ? > the bloat is negligable, Not really > the users are > happier, may be > the resultant code is easier to read... what more could you want? beauty is in the eye of the beholder. > I mean, the "|| die.." code will be written anyway so in the module is a > better place for it, so it doesn't have to be written over and over again! But it is not being written in the module, the user is having to write a sub to process the result. All you are doing is moving when the user processes the result. > As I understand it, this would also clear-up the problem the API currently > has with it's inability to determine if a search returned no results What inability ? $mesg->count will teel you how many results you got. > because there was nothing to return or because of an error performing the > search. You are referring to getting values from an entry, a separate module from the LDAP API module Graham. |