Use of hash variables in module call - puzzling behaviour

Discussion in 'Perl Misc' started by Henry Law, Sep 27, 2005.

  1. Henry Law

    Henry Law Guest

    I have a piece of code that is to send mail using Mail::Internet from my
    Linux server (Perl 5.8.0). It reads variables - the recipient, the
    outbound mail server and so on - from an XML file into a hash.

    Using the variables in the hash causes errors in Mail::Internet; using
    equivalent variables from a hash created from data in the program does
    not cause the same error. Odder still, the error doesn't occur at all
    when I run the same program under ActiveState Perl in Windows.

    Can someone help? Firstly I'm at a loss to understand why this might
    be; secondly I've run out of ideas for debugging the thing.

    The program below simulates the reading of the XML through the use of
    __DATA__; it builds the Mail::Internet structures $header and $mail; it
    then executes the smtp send using first a structure built in the program
    itself ($G_server) and then the XML-derived structure ($g_server). The
    program even checks that the corresponding elements in $g_server and
    $G_server are the same ...

    ----------- sample program ------------
    #! /usr/bin/perl

    use strict;
    use warnings;

    use Mail::Internet;
    use Mail::Header;
    use XML::Simple;

    my @data = <DATA>;
    my $xml = XMLin(join (' ',@data));

    my %g_server;

    $g_server{adminuser} = $xml -> {adminuser};
    $g_server{smtpserver} = $xml -> {smtpserver};
    $g_server{localuser} = $xml -> {localuser};

    my %G_server = (localuser=>'',
    adminuser=>'',
    smtpserver=>'smtp.bt.net');

    my @message = ("Line 1\n","Line 2");

    print ( $g_server{localuser} eq $G_server{localuser} ?
    "localuser same\n" : "localuser different\n");
    print ( $g_server{adminuser} eq $G_server{adminuser} ?
    "adminuser same\n" : "adminuser different\n");
    print ( $g_server{smtpserver} eq $G_server{smtpserver} ?
    "smtpserver same\n" : "smtpserver different\n");


    my $header = Mail::Header->new( ["From:$g_server{localuser}",
    "Sender:$g_server{localuser}",
    "To:$g_server{adminuser}",
    "Subject:Testing"] );

    my $mail = Mail::Internet->new(Header=>$header,Body=>\@message);

    my @recipients;

    print "Sending with G_server variables\n";
    @recipients = $mail->smtpsend(Host=>$G_server{smtpserver},
    MailFrom=>$G_server{localuser},
    To=>$G_server{adminuser});
    print "Mail sent to @recipients\n";

    print "Sending with g_server variables\n";
    @recipients = $mail->smtpsend(Host=>$g_server{smtpserver},
    MailFrom=>$g_server{localuser},
    To=>$g_server{adminuser});
    print "Mail sent to @recipients\n";
    __DATA__
    <nfbserver>
    <adminuser></adminuser>
    <smtpserver>smtp.bt.net</smtpserver>
    <localuser></localuser>
    </nfbserver>

    ----------------- output under Linux ----------------
    [nfb@neptune nfb]$ ./tryit.pl
    localuser same
    adminuser same
    smtpserver same
    Sending with G_server variables
    Mail sent to
    Sending with g_server variables
    Unrecognised line: at blib/lib/Mail/Internet.pm
    (autosplit into blib/lib/auto/Mail/Internet/smtpsend.al) line 616
    ---------------- ends ------------------

    OK, I'm braced for someone finding a simple typo in my code ...
     
    Henry Law, Sep 27, 2005
    #1
    1. Advertising

  2. Henry Law <> wrote in news:1127854648.22344.0
    @sabbath.news.uk.clara.net:

    > Can someone help? Firstly I'm at a loss to understand why this might
    > be; secondly I've run out of ideas for debugging the thing.


    ....
    > @recipients = $mail->smtpsend(Host=>$G_server{smtpserver},
    > MailFrom=>$G_server{localuser},
    > To=>$G_server{adminuser});


    I can't see anything that is obviously wrong, and it would take me a
    little too much effort to test this (as I do not have access to an SMTP
    server that does not require SSL).

    However, have you tried turning debug on?

    @recipients = $mail->smtpsend(
    Host => $G_server{smtpserver},
    MailFrom => $G_server{localuser},
    To => $G_server{adminuser},
    Debug => 1,
    );

    I am not sure if that would help.

    The actual source of the message seems to Mail::Address.pm (line 122 in
    version 1.67).

    I have access to a FreeBSD system (Mail::Address v.1.66) where I tried

    asu1@recex:~ > cat m.pl
    use strict;
    use warnings;

    use Data::Dumper;
    use Mail::Address;

    print Dumper (Mail::Address->parse('') );

    __END__

    asu1@recex:~ > perl m.pl
    $VAR1 = bless( [
    '',
    '',
    ''
    ], 'Mail::Address' );
    asu1@recex:~ >

    Maybe you can try the same script on your Linux system



    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Sep 27, 2005
    #2
    1. Advertising

  3. Henry Law

    Anno Siegel Guest

    Henry Law <> wrote in comp.lang.perl.misc:
    > I have a piece of code that is to send mail using Mail::Internet from my
    > Linux server (Perl 5.8.0). It reads variables - the recipient, the
    > outbound mail server and so on - from an XML file into a hash.
    >
    > Using the variables in the hash causes errors in Mail::Internet; using
    > equivalent variables from a hash created from data in the program does
    > not cause the same error. Odder still, the error doesn't occur at all
    > when I run the same program under ActiveState Perl in Windows.
    >
    > Can someone help? Firstly I'm at a loss to understand why this might
    > be; secondly I've run out of ideas for debugging the thing.


    I don't have the modules in question and was unable to install them
    in a hurry, so what follows is unfounded speculation.

    Are the strings in the hash returned from XMLin normal scalars?
    They *could* be objects with overloaded stringification or tied
    variables in which case something might rub them the wrong way.

    Swap the "Sending with G_server variables" and "Sending with g_server
    variables" blocks. It could be the second call that fails instead of
    depending on which hash is used. Perhaps one of the objects involved
    ($mail or $header) is damaged after the first use.

    Try mixed calls, for example taking adminuser from %G_server and the
    others from %g_server.

    Check versions (Perl, the modules) on the linux box against the
    windows one.

    That's all that comes to mind for now. I have added a couple of remarks
    (untested) to the code below, but these are stylistic and have nothing
    to do with debugging the problem.

    Anno


    > The program below simulates the reading of the XML through the use of
    > __DATA__; it builds the Mail::Internet structures $header and $mail; it
    > then executes the smtp send using first a structure built in the program
    > itself ($G_server) and then the XML-derived structure ($g_server). The
    > program even checks that the corresponding elements in $g_server and
    > $G_server are the same ...
    >
    > ----------- sample program ------------
    > #! /usr/bin/perl
    >
    > use strict;
    > use warnings;
    >
    > use Mail::Internet;
    > use Mail::Header;
    > use XML::Simple;
    >
    > my @data = <DATA>;
    > my $xml = XMLin(join (' ',@data));


    No need for @data.

    my $xml = XMLin join ' ', <DATA>;

    or even

    my $xml = XMLIN do{ local $/; <DATA> };

    should do the same thing. The last one assumes that line feeds and spaces
    are interchangeable as separators.

    > my %g_server;
    >
    > $g_server{adminuser} = $xml -> {adminuser};
    > $g_server{smtpserver} = $xml -> {smtpserver};
    > $g_server{localuser} = $xml -> {localuser};
    >
    > my %G_server = (localuser=>'',
    > adminuser=>'',
    > smtpserver=>'smtp.bt.net');
    >
    > my @message = ("Line 1\n","Line 2");
    >
    > print ( $g_server{localuser} eq $G_server{localuser} ?
    > "localuser same\n" : "localuser different\n");
    > print ( $g_server{adminuser} eq $G_server{adminuser} ?
    > "adminuser same\n" : "adminuser different\n");
    > print ( $g_server{smtpserver} eq $G_server{smtpserver} ?
    > "smtpserver same\n" : "smtpserver different\n");


    print $g_server{ $_} eq $G_server{ $_} ?
    "$_ same\n" : "$_ different\n" for
    qw( localuser adminuser smtpserver);


    > my $header = Mail::Header->new( ["From:$g_server{localuser}",
    > "Sender:$g_server{localuser}",
    > "To:$g_server{adminuser}",
    > "Subject:Testing"] );
    >
    > my $mail = Mail::Internet->new(Header=>$header,Body=>\@message);
    >
    > my @recipients;
    >
    > print "Sending with G_server variables\n";
    > @recipients = $mail->smtpsend(Host=>$G_server{smtpserver},
    > MailFrom=>$G_server{localuser},
    > To=>$G_server{adminuser});
    > print "Mail sent to @recipients\n";
    >
    > print "Sending with g_server variables\n";
    > @recipients = $mail->smtpsend(Host=>$g_server{smtpserver},
    > MailFrom=>$g_server{localuser},
    > To=>$g_server{adminuser});
    > print "Mail sent to @recipients\n";
    > __DATA__
    > <nfbserver>
    > <adminuser></adminuser>
    > <smtpserver>smtp.bt.net</smtpserver>
    > <localuser></localuser>
    > </nfbserver>
    >
    > ----------------- output under Linux ----------------
    > [nfb@neptune nfb]$ ./tryit.pl
    > localuser same
    > adminuser same
    > smtpserver same
    > Sending with G_server variables
    > Mail sent to
    > Sending with g_server variables
    > Unrecognised line: at blib/lib/Mail/Internet.pm
    > (autosplit into blib/lib/auto/Mail/Internet/smtpsend.al) line 616
    > ---------------- ends ------------------
    >
    > OK, I'm braced for someone finding a simple typo in my code ...



    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Sep 28, 2005
    #3
  4. Henry Law

    Henry Law Guest

    Anno Siegel wrote:
    > Henry Law <> wrote in comp.lang.perl.misc:


    >>Using the variables in the hash causes errors in Mail::Internet; using
    >>equivalent variables from a hash created from data in the program does
    >>not cause the same error. Odder still, the error doesn't occur at all
    >>when I run the same program under ActiveState Perl in Windows.


    > Are the strings in the hash returned from XMLin normal scalars?
    > They *could* be objects with overloaded stringification or tied
    > variables in which case something might rub them the wrong way.

    Worth a look. I ran the program under Perl debug and "x"ed the two hashes:
    DB<2> x %g_server
    0 'adminuser'
    1 ''
    2 'smtpserver'
    3 'smtp.bt.net'
    4 'localuser'
    5 ''
    DB<3> x %G_server
    0 'adminuser'
    1 ''
    2 'smtpserver'
    3 'smtp.bt.net'
    4 'localuser'
    5 ''
    .... which looks OK to me, unless I'm missing something.

    > Swap the "Sending with G_server variables" and "Sending with g_server
    > variables" blocks. It could be the second call that fails instead of
    > depending on which hash is used. Perhaps one of the objects involved
    > ($mail or $header) is damaged after the first use.

    I had already tried that; it's the $g_server version that fails
    consistently.

    > Try mixed calls, for example taking adminuser from %G_server and the
    > others from %g_server.

    That's a good idea. I'll try when I'm at home this evening.

    > Check versions (Perl, the modules) on the linux box against the
    > windows one.

    I know the Perl versions are the same; I'll hadn't thought about the
    modules versions and will check.

    > That's all that comes to mind for now.

    Thanks; very helpful.

    I have added a couple of remarks
    > (untested) to the code below, but these are stylistic and have nothing
    > to do with debugging the problem.

    .... which are welcome, thank you. Style is, well, a stylistic thing.

    --

    Henry Law <>< Manchester, England
     
    Henry Law, Sep 28, 2005
    #4
  5. Henry Law

    Guest

    Henry Law <> wrote:
    > Anno Siegel wrote:
    >
    > > Swap the "Sending with G_server variables" and "Sending with g_server
    > > variables" blocks. It could be the second call that fails instead of
    > > depending on which hash is used. Perhaps one of the objects involved
    > > ($mail or $header) is damaged after the first use.


    > I had already tried that; it's the $g_server version that fails
    > consistently.


    That would have been my first recommendation. Second would be to abstract
    away the repeated code, just to make sure there is not some subtle (or
    invisible funky character) difference in the code which executes under the
    two hashes.


    foreach my $hashref (\%g_server, \%G_server) {
    # etc.
    @recipients = $mail->smtpsend(Host=>$hashref->{smtpserver},
    MailFrom=>$hashref->{localuser},
    To=>$hashref->{adminuser}
    );
    # etc.
    };


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Sep 28, 2005
    #5
  6. Henry Law

    Anno Siegel Guest

    Henry Law <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Henry Law <> wrote in comp.lang.perl.misc:

    >
    > >>Using the variables in the hash causes errors in Mail::Internet; using
    > >>equivalent variables from a hash created from data in the program does
    > >>not cause the same error. Odder still, the error doesn't occur at all
    > >>when I run the same program under ActiveState Perl in Windows.


    All this is very puzzling, so I chased down an error with ParserDetails.ini
    and got XML::Simple to install (plus Mail::Internet and Mail::Header).
    However, I cannot reproduce the problem.

    There are several variants of XML::Simple: SAX-based vs. (whatever)-based,
    and Expat-supported or not. What I have is probably SAX without Expat.
    What are you running?

    Something else: Could some encoding deviltry be going on? I believe it
    is possible for strings to be eq, but have different byte representations.
    If that is possible at all it may be worth looking into.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Sep 28, 2005
    #6
  7. Henry Law

    Henry Law Guest

    Anno Siegel wrote:

    >>>Henry Law <> wrote in comp.lang.perl.misc:

    >>
    >>>>Using the variables in the hash causes errors in Mail::Internet; using
    >>>>equivalent variables from a hash created from data in the program does
    >>>>not cause the same error. Odder still, the error doesn't occur at all
    >>>>when I run the same program under ActiveState Perl in Windows.

    >
    >
    > All this is very puzzling, so I chased down an error with ParserDetails.ini
    > and got XML::Simple to install (plus Mail::Internet and Mail::Header).
    > However, I cannot reproduce the problem.

    Anno, thank you for taking the trouble to do that on my behalf. I'm not
    terribly surprised, though, that you couldn't reproduce the problem
    since it only happens to me on Linux and not on Windows. (Come to that,
    I have another Linux machine around - I'll see what happens on there)

    > There are several variants of XML::Simple: SAX-based vs. (whatever)-based,
    > and Expat-supported or not. What I have is probably SAX without Expat.
    > What are you running?

    Hmm; not sure how to find that out. I used the "-m" flag on perldoc
    which showed this header at the top of the module:

    $Id: Simple.pm,v 1.20 2004/04/05 09:12:47

    .... which seems to suggest v1.20 but I don't know about Expat.
    According to the perldoc it does support SAX though.

    > Something else: Could some encoding deviltry be going on? I believe it
    > is possible for strings to be eq, but have different byte representations.
    > If that is possible at all it may be worth looking into.


    Anything's worth looking into just now; and that is possible since the
    original XML file was created on Windows - but I thought it was just
    plain single-byte ASCII. I'll look at the XML with a hex editor to make
    sure.

    As a result of the correspondence on this I've got a long list of "what
    happens if" diagnostics, which I'll have a go at over a day or so. If
    that fails I shall adopt the last resort of the frustrated programmer
    and assign the problem to the usual cause*. Then I'll look for a
    work-round of some kind - maybe assigning the offending variables to an
    intermediate variable would get round the problem. In the mean time,
    thanks.

    * i.e. Spacemen

    --

    Henry Law <>< Manchester, England
     
    Henry Law, Sep 28, 2005
    #7
  8. Henry Law

    Henry Law Guest

    Anno Siegel wrote:
    > Henry Law <> wrote in comp.lang.perl.misc:
    >
    >>Anno Siegel wrote:
    >>
    >>>Henry Law <> wrote in comp.lang.perl.misc:

    >>
    >>>>Using the variables in the hash causes errors in Mail::Internet; using
    >>>>equivalent variables from a hash created from data in the program does
    >>>>not cause the same error. Odder still, the error doesn't occur at all
    >>>>when I run the same program under ActiveState Perl in Windows.


    > Something else: Could some encoding deviltry be going on? I believe it
    > is possible for strings to be eq, but have different byte representations.
    > If that is possible at all it may be worth looking into.


    OK, it's official: my Perl compiler is enchanted. I'll not post the
    whole program, since other people's environments can't reproduce the
    problem anyway, but you'll see what I'm up against. Any ideas on where
    to go from here would be most welcome.

    ----------- non-runnable fragment -----------
    # Succeeds
    my $local = eval '$hash_xml{localuser}';
    sendit ( $local,
    $hash_gen{adminuser},
    'smtp.bt.net'
    );

    # Fails
    $local = $hash_xml{localuser};
    sendit ( $local,
    $hash_gen{adminuser},
    'smtp.bt.net'
    );

    sub sendit {
    my ($localuser,$adminuser,$smtpserver) = @_;
    print "sendit:$localuser, $adminuser, $smtpserver\n";
    print "Local user in hex ",unpack("H*",$localuser),"\n";
    print "Admin user in hex ",unpack("H*",$adminuser),"\n";
    my $header = (... the mail sending code as before)
    ---------------- output ----------------
    [nfb@neptune nfb]$ ./tryit.pl
    sendit:, , smtp.bt.net
    Local user in hex 6e6662406e657074756e652e6c617773686f7573652e6f7267
    Admin user in hex 706f73746d6173746572406c617773686f7573652e6f7267
    Mail sent to
    sendit:, , smtp.bt.net
    Local user in hex 6e6662406e657074756e652e6c617773686f7573652e6f7267
    Admin user in hex 706f73746d6173746572406c617773686f7573652e6f7267
    Unrecognised line: at blib/lib/Mail/Internet.pm
    (autosplit into blib/lib/auto/Mail/Internet/smtpsend.al) line 616
    -------------- ends ----------------
    So the parameters being supplied to the "sendit" subroutine are
    identical at the hexadecimal level, yet one version works and the other
    doesn't.

    BTW it's not that the first successful invocation spoils it for all
    subsequent invocations: I have versions which send successfully three or
    more times, only to fail when the variable comes from the XML hash.

    At least I can see the workround now - use "eval" to fill a temporary
    variable. Nasty but seemingly effective. Maybe I should reinstall Perl
    on the Linux machine but life's too short right now.

    Yours, Mystified of Manchester

    --

    Henry Law <>< Manchester, England
     
    Henry Law, Sep 29, 2005
    #8
  9. Henry Law

    Anno Siegel Guest

    Henry Law <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > Henry Law <> wrote in comp.lang.perl.misc:
    > >>Anno Siegel wrote:
    > >>>Henry Law <> wrote in comp.lang.perl.misc:

    >
    > OK, it's official: my Perl compiler is enchanted. I'll not post the
    > whole program, since other people's environments can't reproduce the
    > problem anyway, but you'll see what I'm up against. Any ideas on where
    > to go from here would be most welcome.
    >
    > ----------- non-runnable fragment -----------
    > # Succeeds
    > my $local = eval '$hash_xml{localuser}';
    > sendit ( $local,
    > $hash_gen{adminuser},
    > 'smtp.bt.net'
    > );
    >
    > # Fails
    > $local = $hash_xml{localuser};
    > sendit ( $local,
    > $hash_gen{adminuser},
    > 'smtp.bt.net'
    > );


    [...]

    Strange indeed.

    All I can think of is to apply random transformations to the string
    (copy it, append '', make it a hash key and retrieve it, capture it
    in a regex, ...) and see if anything has an effect.

    One more thing. The error message is

    > Unrecognised line: at blib/lib/Mail/Internet.pm
    > (autosplit into blib/lib/auto/Mail/Internet/smtpsend.al) line 616


    An installed program shouldn't reside in blib/... but wherever the
    Perl library resides and the path shouldn't be relative. This looks
    like a pre-installation version is used for some reason.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Sep 30, 2005
    #9
  10. Henry Law

    Henry Law Guest

    Anno Siegel wrote:

    > Strange indeed.


    I installed Mail::Internet on another Linux server I have and tried my
    tryit.pl program there - worked perfectly. So the problem manifests
    itself on only my development server, and I have adopted the work-round
    described below. Sooner or later I'll re-install it (probably at FC4)
    and that will cure the problem I'm sure.

    Many thanks to the many and various people who helped me localise the
    problem and tried to find a solution.

    > All I can think of is to apply random transformations to the string
    > (copy it, append '', make it a hash key and retrieve it, capture it
    > in a regex, ...) and see if anything has an effect.


    On the offending server that's what I've done. I probably over-did it,
    but I wrote a little subroutine which copied the characters of the
    offending variable one by one into a new variable and returned it.
    Whatever hex was on the old hash variable is thus destroyed and my
    program works.

    > One more thing. The error message is
    >
    >>Unrecognised line: at blib/lib/Mail/Internet.pm
    >>(autosplit into blib/lib/auto/Mail/Internet/smtpsend.al) line 616

    >
    >
    > An installed program shouldn't reside in blib/... but wherever the
    > Perl library resides and the path shouldn't be relative. This looks
    > like a pre-installation version is used for some reason.


    Hmm; that was the CPAN installer wot did that. Maybe the problem lies
    there; the re-install will sort it out.

    --

    Henry Law <>< Manchester, England
     
    Henry Law, Sep 30, 2005
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Radu
    Replies:
    2
    Views:
    403
  2. André

    very puzzling doctest behaviour

    André, Dec 18, 2007, in forum: Python
    Replies:
    3
    Views:
    246
    André
    Dec 18, 2007
  3. rp
    Replies:
    1
    Views:
    556
    red floyd
    Nov 10, 2011
  4. Ian Macdonald

    Puzzling regex behaviour

    Ian Macdonald, Feb 13, 2007, in forum: Ruby
    Replies:
    23
    Views:
    209
    Ian Macdonald
    Feb 16, 2007
  5. Raphael Clancy

    Puzzling behaviour with range...

    Raphael Clancy, Jan 7, 2009, in forum: Ruby
    Replies:
    5
    Views:
    100
    Dave Bass
    Jan 8, 2009
Loading...

Share This Page