Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have just started using LWP and associated stuff, and with it reduced 800 odd lines of inherited roll-your-own socket stuff down to around twenty lines.

It was working, then I put use strict at the top and found a few potential problems. These I fixed, but managed to completely break the program.

Here's my working function:

use LWP::UserAgent; use HTTP::Request::Common; use URI; sub CreatePriorityAccount{ my $query = shift; my $url = new URI(); $url->scheme( 'http' ); $url->host( getLotusServer() ); $url->path_query( LOTUSPRIPATH ); my $res = $ua->request(POST $url, content-type => 'form-data', content => $query, authorization => "Basic " . AUTHORISATION, ); # Get the Notes DocID from the response if ($res->is_success) { my ( $DocID ) = $res->content =~ /The DocID for this event is +([0-9A-F]*)/; LOG "SUCCESS: $name, Doc ID is $DocID"; StoreDocID( $name, $DocID ); } else{ LOG "FAILED: POST $url"; LOG "RESPONSE: ", $res->code, ": ", $res->message; } }
Now if I put  use strict at the top it complains that bareword content is not allowed with strict subs. If I then change the offending line to
'content-type' => 'form-data',
It appears to work, but the content does not get passed to the server!

I know I can put  no strict 'subs' in a block around the call, but I would rather understand what is going on here and do it properly.

Thanks for your wisdom.

2001-03-15 Edit by Corion: Removed CODE tags (or rather, their remnants) from the node title.

Replies are listed 'Best First'.
Re: How do I use strict with asub( a = 'b' ) syntax?
by merlyn (Sage) on Mar 15, 2001 at 19:44 UTC
    You must have a "bareword" to the left of the arrow for the autoquoting to work, and "content-type" is not a bareword. Fortunately, LWP permits an underscore to be used in a header name, and automatically changes the underscore to a dash, so rewrite your invocation as:
    my $res = $ua->request(POST $url, content_type => 'form-data', content => $query, authorization => "Basic " . AUTHORISATION, );
    and you should be fine.

    -- Randal L. Schwartz, Perl hacker

(ar0n) Re: How do I use strict with sub( a = 'b' ) syntax?
by ar0n (Priest) on Mar 15, 2001 at 18:58 UTC
    Change
    my $res = $ua->request(POST $url, content-type => 'form-data', content => $query, authorization => "Basic " . AUTHORISATION, );
    to
    my $res = $ua->request(POST $url, [ "content-type" => 'form-data', "content" => $query, "authorization" => "Basic " . AUTHORISATION ]);
    Note the brackets around your request.

    [ar0n]

Re: How do I use strict with asub( a = 'b' ) syntax?
by davorg (Chancellor) on Mar 15, 2001 at 19:00 UTC

    (your title doesn't really match up with the problem as described)

    The => operator generally quotes the value on its left hand side. There are however exceptions, and you've stumbled across one of them. The automatic quoting only works when all of the characters in the key name are 'word' characters (i.e. ones that match \w in regular expressions). The string 'content-type' contains a '-' which isn't a world character. Unquoted, Perl interprets that as 'content' - 'type' which doesn't make much sense. The best way round this problem is to quote the key.

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      But note that -color => "red" works just fine. Unary minus has been made extra special just for this case (because of tcl syntax inherited via Tk). (:

              - tye (but my friends call me "Tye")
Re: How do I use strict with asub( a = 'b' ) syntax?
by Anonymous Monk on Mar 16, 2001 at 14:05 UTC
    Thanks to all the monks who helped with this.

    First of all apologies for cutting too much out of the piece of code I quoted. LOG is a function that logs a message, AUTHORISATION and LOTUSPRIPATH are constants provided by the sub MYCONSTANT{ "constvalue" } idiom. I missed out the crucial line

    my $ua = new LWP::UserAgent;

    My problem in a nutshell is that if I quote the key then the values do not end up getting passed. So when I tried the first solution, adding the brackets, it failed to authorise because the authorisation value did not get passed. Randall's solution worked, because it did not involve quoting the key, and thankyou very much.

    I think my problem is I don't understand the syntax of

    my $res = $ua->request(POST $url, content_type => 'form-data', content => $query, authorization => "Basic abc", );
    I guess POST is a function from HTTP::Request::Common returning the request as a hash, but why it doesn't allow actual quoting of the keys is a mystery. Understanding of this is clearly at a higher level of enlightenment.
      Now I have a higher state of enlightenment.

      The only reason it worked before was a fluke. For form-data I would need  content => [ @query ] but I was sending in  content => $query , which requires x-www-form-urlencoded. Luckily for me, content-type is a sum which yields zero, so the header said 0 => form-data and the default content-type was put in.

      Aaah! Said Stork.

      I will be more careful in future and use strict from the start!

Re: How do I use strict with asub( a = 'b' ) syntax?
by Jouke (Curate) on Mar 15, 2001 at 19:06 UTC
    When I try this code with perl -w and use strict I get a lot more problems than that line you point out. For example, where does the $ua come from? Is LOG a subroutine? Is LOTUSPRIPATH a scalar?

    It's hard to give you advice in this case if we don't know more of the surrounding code and the purpose of the piece of code you're posting.

    Jouke Visser, Perl 'Adept'