Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Re: Extending MIME::Lite

by demerphq (Chancellor)
on Sep 27, 2003 at 13:23 UTC ( #294640=note: print w/ replies, xml ) Need Help??


in reply to Re: Extending MIME::Lite
in thread Extending MIME::Lite

I'm thinking of intercepting the hashref before calling new. So that

require Net::SMTP; my $smtp = MIME::Lite::SMTP->new(@args) or Carp::croak("Failed to connect to mail server: $!\n");

becomes something like...

require Net::SMTP; my $smtp; if (ref $args[0]) { $opts = shift @args; # handle special cases, and finally resulting in a usable valu +e # in $smtp. } else { $smtp = MIME::Lite::SMTP->new(@args) or Carp::croak("Failed to connect to mail server: $!\n"); }

So before MIME::Lite::SMTP even gets called @args has been precleaned as appropriate. This would allow special cases like having a list of SMTP hosts that are tried until one lets us in, or handling authentication, or turning Debug on in Net::SMTP without having to do the ugly Net::SMTP->new(undef,Debug=>1) in the user code (inside MIME::Lite its ok to do this, as in there its unlikely to cause trouble to a newbie).

Also I agree quite a bit with your points about positional arguments. The only quibble I have is from Perls flexibility with arguments and weakish typing. You can often extend positional arguments by getting creative with types. For instance the trick above works out because its extremely unlikely that somebody is using a blessed reference as a hostname. In fact I could get a lot more picky and check that the ref is a HASH and that if it is a hash that stringification is not overloaded. This would result in total backwards compatibility while still allowing extension.

Cheers,


---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi



Comment on Re: Re: Extending MIME::Lite
Select or Download Code
Re: Re: Re: Extending MIME::Lite
by trs80 (Priest) on Sep 27, 2003 at 14:24 UTC
    The else doesn't need to be there. The $smtp is still going to need to be created in the same way (or at least it seems so to me). The authentication action occurs after the Net::SMTP object has been created, which was part of my initial concern when adding support to MIME::Lite. I am still working through why Net::SMTP doesn't allow for the authentication arguments in the object creation. It would seem that Net::SMTP should perhaps be the one that bends and allows for the authenication to be passed into it on object creation.

    If we moved this logic into the Net::SMTP module, what would happen if we did this right before we return the Net::STMP object:
    if (defined $arg{User}) { $obj->auth($arg{User},$arg{Password}); }
    inside of the Net::SMTP new? Then when we create a new Net::SMTP call we do it as:
    MIME::Lite->send('smtp', $out_smtp , Port =>$smtp_port , Timeout=>60 , Debug => $debug , Hello => 'domain.com', User => 'trs80', Password => 'blah' );
    My simple test indicates that it works, but I need to carefully review the side effects of performing the auth in the object creation.

    Placing the change inside of Net::SMTP makes more sense in that it keeps the logic in the right problem space and thereby making it benefical to a larger user base.

      The else doesn't need to be there. The $smtp is still going to need to be created in the same way (or at least it seems so to me).

      Key term here is need. Yes you are correct it doesnt need to be there, but the idea I had was that this extension is not only going to cover the case of authentication. One thing I would like to do is implement smart hosts. The user should be a able to supply a list of SMTP hosts and have MIME::Lite cycle through them until it manages to send its mail. So for what I have in mind keeping the simple case seperate from the more complex case makes sense.

      Placing the change inside of Net::SMTP makes more sense in that it keeps the logic in the right problem space and thereby making it benefical to a larger user base.

      Agreed. However I think you may be waiting a while before such a patch is implemented. Probably longer than it will take to go into MIME::Lite. If MIME::Lite does its own ting, and then sometime down the path Net::SMTP is altered as you say then MIME::Lite can be modified accordingly. Until that day Id rather think about what is directly under my control than what would be possible when a patch is applied to a module I have no control over.


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi


Re: Re: Re: Extending MIME::Lite
by trs80 (Priest) on Sep 27, 2003 at 17:52 UTC
    This reply is to address the change if the modification takes place in MIME::Lite vs. Net::SMTP as my previous post suggests. I think the change in behavior should occur at the send method rather then the send_by_smtp. This would allow future modifications of send methods to accounted for in the same manner. So here is my proposed revised sub send:
    # add new global that the top my $SenderOpts = ''; sub send { my $self = shift; if (ref($self)) { ### instance method: my ($method, @args); if (@_) { ### args; use them just t +his once $method = 'send_by_' . shift; @args = @_; } else { ### no args; use defaults $method = "send_by_$Sender"; @args = @{$SenderArgs{$Sender} || []}; } $self->verify_data if $AUTO_VERIFY; ### prevents missing part +s! return $self->$method(@args); } else { ### class method: if (@_) { my @old = ($Sender, @{$SenderArgs{$Sender}}); $Sender = shift; if ( ref($_[0]) eq 'HASH') { $SenderOpts = shift; } $SenderArgs{$Sender} = [@_]; ### remaining args return @old; } else { Carp::croak "class method send must have HOW... arguments\n" +; } } }
    Then below in our send_by_smtp method we add:
    if ($SenderOpts) { $smtp->auth( $SenderOpts->{auth_username}, $SenderOpts->{auth +_password} ); }
    directly after our $smtp object is created.

      I think the change in behavior should occur at the send method rather then the send_by_smtp.

      I can see what you are getting at here, but it doesnt take into account the full interface of MIME::Lite. We need to handle two distinct cases. The first is that someone uses MIME::Lite->send() to configure the class defaults. The second is that someone calls $mime_obj->send_by_smtp() to override the class defaults or simply because they are doing a quick and dirty, or more likely because they are a beginner and havent groked send() properly.

      Thus whatever processing happens in send() will also have to happen in send_by_smtp (and most likely send_by_sendmail and send_by_sub too). This isn't to say that send() wont be changed, just to say that it doesnt remove the requirement to alter send_by_smtp() as well.


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi


Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://294640]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (14)
As of 2014-10-22 13:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (118 votes), past polls