Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   returning references, etc. (http://www.velocityreviews.com/forums/t894529-returning-references-etc.html)

Dave 10-04-2005 12:34 PM

returning references, etc.
 
Hi,

I have one routine called "browserbuilder" which builds a moderately
complex LWP user agent, among other things. I want to be able to call
the browserbuilder sub from another routine and have browserbuilder
return the browser object to that subroutine. I then want that
subroutine to return the browser object when it is called from another
routine, which will end up using the browser object.

I clearly have something wrong, but I have not delt with objects and
references enough to figure out what. Can anyone tell me how to do it
correctly or point me in the right direction?

Thanks,
Dave
------------------------------------------------

I have a certain point in the browserbuilder subroutine right now that
looks like this:
if ($vlinkcall eq "yes")
{

$xbrowser->max_size(undef); # i built the rest of $xbrowser
elsewhere
return \$xbrowser; #$xbrowser is the name of my LWP::UserAgent
object
}

The command in the second subroutine, called "load_browser", which
calls the browserbuilder subroutine looks like this:

$browser=&browserbuilder($xurlid, $xusername, $xurl, $xtimezone,
$xauthusername, $xauthpassword, $xpostdata, $xcookieurl, $xrefurl,
$xtextstring1, $xtextstring2, $xaltcode, $xhackerchecksum, $i,
$xpalerts, $xsalerts, $xcheckrecovery, $xauthtype, $newchecksum,
$xlinkcall);

return \$browser;


The routine that needs the browser object uses this code:

$xbrowser=&load_browser($vurlid);
$xresponse= $xbrowser->get($murl);

The error message is:
Can't call method "get" on unblessed reference at ./simplelinks.cgi
line 80.


Paul Lalli 10-04-2005 01:19 PM

Re: returning references, etc.
 
Dave wrote:
> I have one routine called "browserbuilder" which builds a moderately
> complex LWP user agent, among other things. I want to be able to call
> the browserbuilder sub from another routine and have browserbuilder
> return the browser object to that subroutine. I then want that
> subroutine to return the browser object when it is called from another
> routine, which will end up using the browser object.
>
> I clearly have something wrong, but I have not delt with objects and
> references enough to figure out what. Can anyone tell me how to do it
> correctly or point me in the right direction?


Your central confusion seems to stem from not realizing that objects
*are* references. In general, you do not pass or return references to
objects; you pass and return the objects themselves.

> I have a certain point in the browserbuilder subroutine right now that
> looks like this:
> if ($vlinkcall eq "yes")
> {
>
> $xbrowser->max_size(undef); # i built the rest of $xbrowser
> elsewhere
> return \$xbrowser; #$xbrowser is the name of my LWP::UserAgent
> object
> }


return $xbrowser;

> The command in the second subroutine, called "load_browser", which
> calls the browserbuilder subroutine looks like this:
>
> $browser=&browserbuilder($xurlid, $xusername, $xurl, $xtimezone,
> $xauthusername, $xauthpassword, $xpostdata, $xcookieurl, $xrefurl,
> $xtextstring1, $xtextstring2, $xaltcode, $xhackerchecksum, $i,
> $xpalerts, $xsalerts, $xcheckrecovery, $xauthtype, $newchecksum,
> $xlinkcall);


Don't call subroutines using the & in front of the subroutine name
unless you know what that does and you want that added functionality.
99% of the time, you don't.

> return \$browser;


return $browser;

> The routine that needs the browser object uses this code:
>
> $xbrowser=&load_browser($vurlid);
> $xresponse= $xbrowser->get($murl);
>
> The error message is:
> Can't call method "get" on unblessed reference at ./simplelinks.cgi
> line 80.


The problem is that at this point in your code, $xbrowser is a
reference to the object, not the object itself.

An example that eliminates the object-layer of confusion:

my @array = (1..10);
my $ref = \@array;
my $refref = \$ref;

$refref is a reference to a reference to an array. If you attempted to
access the first element of the array (as you were attempting to access
a method earlier) by using:
print "First element: $refref->[0]\n";
you would get the error "Not an ARRAY reference".

Once you understand the problem with the above example, it is easily
translated to your original problem by understanding that all Perl
objects *are* references (usually, but not always, references to
hashes). They are simply references that happen to have been blessed
into a class.

Hope this helps,
Paul Lalli


Dave Weaver 10-04-2005 01:22 PM

Re: returning references, etc.
 
On 4 Oct 2005 05:34:19 -0700, Dave <dszostek@gmail.com> wrote:
>
> I have a certain point in the browserbuilder subroutine right now that
> looks like this:
> if ($vlinkcall eq "yes")
> {
>
> $xbrowser->max_size(undef); # i built the rest of $xbrowser
> elsewhere


By the look of it (but I can't be sure because you've not shown the
relevant code), here $xbrowser is a blessed reference (i.e. an
'object').

I reccommend you find the posting guidelines that are posted here
regularly; they'll provide you with some great tips on how to get
the best answers from this group. One such tip is to post a *short*
but *complete* program that exhibits your problem; this allows others
to cut-and-paste the code and see the problem for themselves.

> return \$xbrowser; #$xbrowser is the name of my LWP::UserAgent


Here you return a reference to that reference.
I suspect this should be
return $xbrowser;


> object
> }
>
> The command in the second subroutine, called "load_browser", which
> calls the browserbuilder subroutine looks like this:
>
> $browser=&browserbuilder($xurlid, $xusername, $xurl, $xtimezone,

^
This & is superfluous here; if you don't know what its effects are,
you don't need it;
$browser = browserbuilder($xurlid, $xusername, $xurl, $xtimezone,

> $xauthusername, $xauthpassword, $xpostdata, $xcookieurl, $xrefurl,
> $xtextstring1, $xtextstring2, $xaltcode, $xhackerchecksum, $i,
> $xpalerts, $xsalerts, $xcheckrecovery, $xauthtype, $newchecksum,
> $xlinkcall);
>
> return \$browser;


Here, again, you're returning a refernce to what is presumably
(although I can't be sure because you've just posted semi-random
snippets of code) also a blessed reference.

return $broswer;

>
> The routine that needs the browser object uses this code:
>
> $xbrowser=&load_browser($vurlid);


So now, if I understand your description of your code correctly,
$xbrowser is a reference to a reference to a blessed reference...


> $xresponse= $xbrowser->get($murl);
>
> The error message is:
> Can't call method "get" on unblessed reference at ./simplelinks.cgi
> line 80.


That's because $xbrowser isn't a blessed reference;
it's a reference to a reference to one.

Descriptions of error messages can be found in "perldoc perldiag"

Dave 10-04-2005 02:12 PM

Re: returning references, etc.
 
Hi,

Thanks for your help. Per your suggestion, I broke down the code into a
small program that could be copied and pasted. I ran it and to my
surprise it worked how I thought it should.

Why is it that I would not want to use '&' when calling subroutine
names? It is a habit I've gotten into for no rhyme or reason. What does
it do?

Thanks for helping me break this down more. I pasted the code below in
case you wanted to see it.

~dave
-----------------------
#!/usr/bin/perl
use LWP;

&sub3; # I want to see a status code printed

sub sub1
{
my $xbrowser=LWP::UserAgent->new(
'agent' => "UltraUptime/1.0 (compatible; MSIE 6.0;
Windows NT 5.1)",
'max_size' => "1024",
'timeout' => "30",
'keep_alive' => 1
);
return $xbrowser;
}
sub sub2
{
$browser2=&sub1;
return $browser2;
}
sub sub3
{
$browser3=&sub2;
$xresponse= $browser3->get('http://www.yahoo.com');
print "HTTP Response: " . $xresponse->code() . "\n";
}

#my @array = (1..10);
#my $ref = \@array;
#my $refref = \$ref;
#print "First element: $refref->[0]\n";


Paul Lalli 10-04-2005 02:21 PM

Re: returning references, etc.
 
Dave wrote:
> Thanks for your help. Per your suggestion, I broke down the code into a
> small program that could be copied and pasted. I ran it and to my
> surprise it worked how I thought it should.


I'm confused by your surprise. Two different people told you what you
were doing wrong, and how to correct it. You made the appropriate
corrections. Had you assumed we were lying to you?

> Why is it that I would not want to use '&' when calling subroutine
> names? It is a habit I've gotten into for no rhyme or reason. What does
> it do?


perldoc perlsub

It has two effects:
1) If called without any explicit parameters (ie, &myfunc;), will
automatically pass the current value of @_ as parameters.
2) Disables prototype checking. Prototypes are completely ignored if &
is used.

Paul Lalli


Dave 10-04-2005 02:43 PM

Re: returning references, etc.
 
Hi Paul,

I certainly did not think anyone was misleading me. I thought I had
tried it like that the first time. That's how I assumed it should be
done. When it didn't work I started doing wacky things. After reading
your responses, I broke it down back to what I thought I had tried
initially without re-reading your responses in depth. I wanted to get
the error to happen in a small block of code so I could re-read the
responses in depth and fix it. My surprise was that it worked the first
time, not that I was provided correct, useful information :)

Thanks again for your help! I really appreciate it.
~dave


A. Sinan Unur 10-04-2005 11:58 PM

Re: returning references, etc.
 
"Dave" <dszostek@gmail.com> wrote in news:1128437007.671157.98310
@f14g2000cwb.googlegroups.com:

> I broke it down back to what I thought I had tried
> initially without re-reading your responses in depth. I wanted to get
> the error to happen in a small block of code so I could re-read the
> responses in depth and fix it. My surprise was that it worked the first
> time, not that I was provided correct, useful information :)


Which is why the posting guidelines strongly recommend you do this as part
of your efforts to solve the problem.

Sinan

--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

Bertilo Wennergren 10-05-2005 02:45 AM

Subroutines with & (was: Re: returning references, etc.)
 
Paul Lalli:

> Don't call subroutines using the & in front of the subroutine name
> unless you know what that does and you want that added functionality.
> 99% of the time, you don't.


I'll jump in on a tangent here:

I've tried to do things like you say, calling subroutines without "&", but
lately I've had the compiler sometimes complain about the wrong number of
arguments (which was never true!), and I've found that the only solution
was to add a "&" to the subroutine call. This seems to happen most often in
regular expressions (with an "e" switch), but also in some other cases. I
have no idea what's going on here. Does anyone have an idea?

I'm sorry I don't have any actual code examples. When it happens I now
almost routinely add "&" and move on, never understanding why all of a
sudden the extra "&" was required.

If necessary maybe I'll be able to create an example.

(BTW, I always do "use strict.")

--
Bertilo Wennergren <http://bertilow.com>

A. Sinan Unur 10-05-2005 03:02 AM

Re: Subroutines with & (was: Re: returning references, etc.)
 
Bertilo Wennergren <bertilow@gmail.com> wrote in
news:dhveo1$nq7$1@domitilla.aioe.org:

> Paul Lalli:
>
>> Don't call subroutines using the & in front of the subroutine name
>> unless you know what that does and you want that added functionality.
>> 99% of the time, you don't.

>
> I'll jump in on a tangent here:
>
> I've tried to do things like you say, calling subroutines without "&",
> but lately I've had the compiler sometimes complain about the wrong
> number of arguments


I would be interested to see how you get perl to complain about an
incorrect number of arguments to a sub.

Are you using prototypes? If you are using prototypes, and need to
disable prototype checking to get the program to work properly, why are
you using prototypes?

> I'm sorry I don't have any actual code examples. When it happens I now
> almost routinely add "&" and move on, never understanding why all of a
> sudden the extra "&" was required.
>
> If necessary maybe I'll be able to create an example.


It is not necessary for our benefit. It might be necessary for you to be
able to understand what you are doing wrong.

Sinan


--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html

Tad McClellan 10-05-2005 03:25 AM

Re: Subroutines with & (was: Re: returning references, etc.)
 
Bertilo Wennergren <bertilow@gmail.com> wrote:
> Paul Lalli:
>
>> Don't call subroutines using the & in front of the subroutine name
>> unless you know what that does and you want that added functionality.
>> 99% of the time, you don't.

>
> I'll jump in on a tangent here:
>
> I've tried to do things like you say, calling subroutines without "&", but
> lately I've had the compiler sometimes complain about the wrong number of
> arguments (which was never true!),



You probably shouldn't be using prototypes either, they don't do
what most people expect them to do.


> and I've found that the only solution
> was to add a "&" to the subroutine call.



Which overrides prototypes, ie. it is in Paul's "one percent".

But you still probably shouldn't be using prototypes.


> This seems to happen most often in
> regular expressions (with an "e" switch),



There are no subroutines involved with regular expressions,
so you must have entered the Twilight Zone or something.


> but also in some other cases. I
> have no idea what's going on here. Does anyone have an idea?
>
> I'm sorry I don't have any actual code examples.



We will be able to answer your question when you come up with one,
until then there is no telling...


> When it happens I now
> almost routinely add "&" and move on, never understanding why all of a
> sudden the extra "&" was required.



Because you are (attempting to) use prototypes on your function definitions.

Cargo cult programming is just plain silly!


--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas


All times are GMT. The time now is 12:39 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.