I'm writing a SOAP Server in perl and I need/want to use objects. I
have an array called @users which is populated in sub new. I want to
store this array in my $self variable which is passed to all functions
and then pull it out later. Can somebody help me?
sub new
{
my ($class_name) = @_;
my ($self) = {};
bless ($self, $class_name);
my $phill = new user;
$phill->setId(6);
$phill->setUsername("ptaylor");
$phill->setPassword("password");
$phill->setSessionKey("");
#cut some code out to stop the post being enormous.
my @users = ( $phill );
$self->{'users'} = [ @users ];
return $self;
}
sub login
{
my ($self, $username, $password) = @_;
my @users = @$self->{'users'}; #<--
THIS IS LINE 62
foreach my $user (@users)
#more code....
}
how I get this message in my VB Soap Client:
Can't use string ("user_management") as an ARRAY ref while "strict
refs" in use at user_management.pm line 62.
Phill
This message means that $self->{'users'} is returning a string, and
not an arrayref, so you can't dereference it as an array.
>
> My question is how to I put an array into a hash (if $self is one. I
> don't really know) and how do I get it out again intact?
If by 'put an array into a hash' you mean assign an arrayref value to
a hash key, then:
my @ar = qw( 1 two blue );
$hash{'key'} = \@ar;
or
$hash{'key'} = [ 'hello', 'world' ];
Ok, thanks dude. So if I have my code do this:
$self->{'users'} = \@users;
how do I pull the data out again later when I need it?
I've tried:
my @users = ref $self->{'users'}; //same message as above
my @users = @$self->{'users'};
my @users = \$self->{'users'};
my @users = map $self->{'users'}; //gave 500 internal server err
my @users = ( $self->{'users'} ); //same as original err
my @users = scalar $self->{'users'};
I have no idea what the hell I'm doing or what any of these keywords
mean. All I want to do is pull that array back into a variable. Anyone?
> my @users = ref $self->{'users'}; //same message as above
> my @users = @$self->{'users'};
> my @users = \$self->{'users'};
> my @users = map $self->{'users'}; //gave 500 internal server err
> my @users = ( $self->{'users'} ); //same as original err
> my @users = scalar $self->{'users'};
You are ignoring the fact that programming is a deterministic endeavor.
Successful programmers are not those who throw a bazillion variations at
a wall and see what sticks.
> I have no idea what the hell I'm doing or what any of these keywords
> mean.
Well, this would be the time to learn then, wouldn't it?
You can start by buying yourself a beginners' Perl book, oh, I don't
know, "Learning Perl" might work
(http://www.oreilly.com/catalog/lperl3/)
At the very least, you should have read:
perldoc perlreftut
perldoc perldsc
> All I want to do is pull that array back into a variable. Anyone?
If $x is a reference to an array, then @{ $x } dereferences it.
my @users = @{ $self->{users} };
Sinan
--
A. Sinan Unur <1u...@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
@users will hold exactly one thing, $phill. Why use an array for that?
>
> $self->{'users'} = [ @users ];
>
> return $self;
>
> }
> sub login
> {
> my ($self, $username, $password) = @_;
> my @users = @$self->{'users'}; #<--
> THIS IS LINE 62
>
>
> how I get this message in my VB Soap Client:
>
> Can't use string ("user_management") as an ARRAY ref while "strict
> refs" in use at user_management.pm line 62.
The problem is in some part of the code you didn't show us.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
The array only held one value because I didn't want to post an
enourmous block of text. Anyway here is the entire copy of the code.
Each instance gets an array of three people called @users. It's shoved
into $self->{'users'}. Then in each function I want to pull it out
again but I can't seem to do it. The query functions shows there are
no users what so ever in the array:
#!/usr/bin/perl -w
package user_management;
use user;
#use strict;
sub new
{
my ($class_name) = @_;
my ($self) = {};
bless ($self, $class_name);
#some objects for the array
my $phill = new user;
$phill->setId(6);
$phill->setUsername("ptaylor");
$phill->setPassword("password");
$phill->setSessionKey("");
my $simon = new user;
$simon->setId(7);
$simon->setUsername("sroberts");
$simon->setPassword("cheese");
$simon->setSessionKey("");
my $nick = new user;
$nick->setId(8);
$nick->setUsername("nick");
$nick->setPassword("rock");
$nick->setSessionKey("");
#put them in the array
my @users = ( $phill, $simon, $nick );
$self->{'users'} = \@users; #put the array in an instance variable
(or perl equiv)
$self->{'nextSessionId'} = 1;
return $self;
}
sub login
{
my ($self, $username, $password) = @_;
#print "usr: $username\npwd: $password\n";
#my $size = @users;
#;return "ERR: Count is $size";
#return "ERR: I GOT $username, $password";
my @users = @{ $self->{'users'} };
foreach my $user (@users)
{
if ($user->getUsername() eq $username)
{
if ($user->getPassword() eq $password)
{
if ($user->getSessionKey ne "")
{
return "ERR: User already logged in";
}
else
{
#generate session key
$user->setSessionKey("SESS" . $self->{'nextSessionId'});
$self->{'nextSessionId'} = $self->{'nextSessionId'} + 1;
return $user->getSessionKey();
}
}
else
{ return "ERR: Password is wrong"; }
}
}
return "ERR: No users";
}
sub query
{
my $self = shift;
my @users = @{ $self->{'users'} };
my $active = 0;
my $total = @users;
my $retval = "";
foreach my $usr (@users)
{
if ($usr->getSessionKey() ne "")
{
$retval = $retval . "user " . $usr->getUsername() . " logged in\n";
$active++;
}
else
{
$retval = $retval . "user " . $usr->getUsername() . " logged out
\n";
}
}
return "$retval$active of $total";
}
sub logout
{
my ($self, $sessionKey) = @_;
my @users = @{ $self->{'users'} };
foreach my $usr (@users)
{
if ($usr->getSessionKey() eq $sessionKey)
{
$usr->setSessionKey("");
return 1;
}
}
return 0;
}
1;
--
Before anyone makes a note of it - I am aware that each instance of
the user_management object will get a duplicate array. This isn't my
primary concern at the moment however. I just want to be able to store
arrays inside object instances.
I already own programming perl by Larry Wall. It's sitting here on my
desk. However it happens to be over 900 pages and the author spends
all his time setting up jokes and "funny" lines of code rather than
actually explain in programming terms what the hell is going on. I'm
more gutted I brought this book than the time I dropped my wallet down
a drain. That tells you something.
Page 245: "the backslash operator. "The operator works like the &
(address-of) operator in C -- at least at first glance."
-- Well I know C and I know how to use the address of operator, so how
do I deference it? No...the authors off telling you what other "clever
little lines of code" you can make with Perl.
$coderef = sub { print "Boink\n" };
Wow this is awesome. Turn the page and you learn how to "bless your
doggie". I'm sold. I mean that's on line 245...The chapter on data
structures starts on page 269 man. Surely data structures are more
important than anonymous functions?
Look I know I am going to have to read the book no matter how much of
a frustrating read it is. However I do want to get this prototype
running prior to my intellectual investment. I don't want to read 900
pages when effectively the prototype I'm writing is going to say
whether the language is feasible or not, not my willingness or
unwillingness to learn it.
I already own programming perl by Larry Wall. It's sitting here on my desk. However it happens to be over 900 pages
and the author spends all his time setting up jokes and "funny" lines of code rather than actually explain in programming terms what the hell is going on.
I'm more gutted I brought this book than the time I dropped my wallet down a drain. That tells you something.
Page 245: "the backslash operator. "The operator works like the & (address-of) operator in C -- at least at first glance."
-- Well I know C and I know how to use the address of operator, so how do I deference it?
No...the authors off telling you what other "clever little lines of code" you can make with Perl.
$coderef = sub { print "Boink\n" };
Wow this is awesome.
Turn the page and you learn how to "bless your doggie". I'm sold. I mean that's on line 245...The chapter on data
structures starts on page 269 man. Surely data structures are more important than anonymous functions?
Look I know I am going to have to read the book no matter how much of a frustrating read it is.
However I do want to get this prototype running prior to my intellectual investment.
I don't want to read 900 pages when effectively the prototype I'm writing is going to say whether the language is feasible or not, not my willingness or unwillingness to learn it.
> On May 1, 3:44 pm, "A. Sinan Unur" <1...@llenroc.ude.invalid> wrote:
>> Philluminati <Phillip.Ross.Tay...@gmail.com> wrote in news:661262f3-
>> aea5-4734-906e-7062d77f2...@m44g2000hsc.googlegroups.com:
...
>> > All I want to do is pull that array back into a variable. Anyone?
>>
>> If $x is a reference to an array, then @{ $x } dereferences it.
>>
>> my @users = @{ $self->{users} };
>>
>> Sinan
>>
>> --
>> A. ...
Do not quote sigs.
<snip rant>
In your haste, you seem to have missed the answer to your question.
Sinan
--
A. Sinan Unur <1u...@llenroc.ude.invalid>
> package user_management;
Generally you don't want a lower case name for your package.
>
> use user;
> #use strict;
Why comment that out?
>
> sub new
> {
> my ($class_name) = @_;
>
> my ($self) = {};
> bless ($self, $class_name);
Little cleaner as:
my $self = bless {}, $class_name;
>
> #some objects for the array
This stuff would typically be found in an init method, or
passed in to new or something other than having new
create it. Keep your new method short and simple.
> my $phill = new user;
> $phill->setId(6);
> $phill->setUsername("ptaylor");
> $phill->setPassword("password");
> $phill->setSessionKey("");
[...]
>
> #put them in the array
> my @users = ( $phill, $simon, $nick );
>
> $self->{'users'} = \@users; #put the array in an instance variable
> (or perl equiv)
You might want to create an add_user method, instead of doing that. e.g.
$self->add_user( $phill );
That way it'd be much easier to test also. You would call the add_user
from whatever is using this class.
> $self->{'nextSessionId'} = 1;
Probably want a nextSessionId and/or sessionId method for that too.
>
> return $self;
>
> }
>
> sub login
> {
> my ($self, $username, $password) = @_;
> my @users = @{ $self->{'users'} };
Create a get_user method.
>
> foreach my $user (@users)
You probably want to use a hashref, instead of an array, that
way you have one look-up instead of iterating over many
@users.
> {
> if ($user->getUsername() eq $username)
> {
> if ($user->getPassword() eq $password)
> {
> if ($user->getSessionKey ne "")
>
]...]
> --
>
> Before anyone makes a note of it - I am aware that each instance of
> the user_management object will get a duplicate array. This isn't my
> primary concern at the moment however. I just want to be able to store
> arrays inside object instances.
Based on your code above, using a hash would be much more efficient.
--
Christopher Mattern
NOTICE
Thank you for noticing this new notice
Your noticing it has been noted
And will be reported to the authorities
Isn't also about trial and error? Especially, but not limited to, people
who are young in this field of study? How does one learn something if
they do not run some tests? That is more or less how I advanced so deep
into programming many moons ago, trying to see if this works, what this
that do, what happens if I do this, etc. Albeit, one should keep
documentation close by too, but trial and error *is* a as big a part as
anything IMHO.
--
szr
Maybe a better analogy would be putting tape over the warning lights
(check engine, ...) in your car.
--
szr
> A. Sinan Unur wrote:
>> Philluminati <Phillip.R...@gmail.com> wrote in news:661262f3-
>> aea5-4734-906...@m44g2000hsc.googlegroups.com:
>>
>>> my @users = ref $self->{'users'}; //same message as above
>>> my @users = @$self->{'users'};
>>> my @users = \$self->{'users'};
>>> my @users = map $self->{'users'}; //gave 500 internal server err
>>> my @users = ( $self->{'users'} ); //same as original err
>>> my @users = scalar $self->{'users'};
>>
>> You are ignoring the fact that programming is a deterministic
>> endeavor. Successful programmers are not those who throw a bazillion
>> variations at a wall and see what sticks.
>
> Isn't also about trial and error? Especially, but not limited to, people
> who are young in this field of study? How does one learn something if
> they do not run some tests?
Throwing a bunch of random gibberish at the compiler will eventually give
you a result that "works," in the same sense that infinite monkeys with type-
writers will eventually produce Shakespeare. But the process will leave you
none the wiser as to *how* it works, or *why* the other attempts failed.
As a student learning a new language, the understanding of "how" and "why"
is as important, or more so, than a working finished program.
Yes, at some point you have to write something and try it. But, before you
get to there, you should have an idea of what you expect the code to do. If
the results are as you expect, all is well and good. If not, then you need
to examine the code again, break it down into its components, and figure
out which of those parts is not behaving how you expected it to - and then
change your expectations accordingly.
sherm--
--
My blog: http://shermspace.blogspot.com
Cocoa programming in Perl: http://camelbones.sourceforge.net
I need to see if this language is feasible as a SOAP Server, even
though there is little support in Perl's weakly typed language to
generate WSDL files automatically compared to Java, C/C++, .NET and
most other languages. You can't honestly expect me to read 900 pages
just for a small sample. If I wanted to try out in 4 languages I'd
basically have to read 3600 pages. **It only has to work**, it doesn't
have to work well. I just want to see how complicated it's going to
be. I already have a soap sample working but I now I want to extend it
with instances of objects and this is where it's all going wrong. The
objects aren't being remembered across the session - or at least
that's what I think.
When I test user_management.pm with my test script. The output is what
I expect. When I try to use it in soap I get this:
When I take out the line that says "use strict" I get this:
perhaps I can be forgiven for actually "closing my eyes" since it only
happens in the SOAP client -> Soap Server example and it doesn't
happen when I run a test script directly against user_management.pm.
---
I think the function returns "0 of 0" because the class variables are
not being remembered. That's my feeling and that's the question I was
looking to solve but apparently I have been branded as ignorant
because I wanted to postpone reading a book until after I solved it.
The fact I have constructed an existing SOAP Server example, have
already demonstrated a considerable knowledge for someone who hasn't
yet read a book doesn't seem to count for anything. There seems to be
an invisible threshold of questions. The simpler the question the more
is warrants abuse from a developer's misunderstanding of the
fundamentals.
Anyway I have posted the code below and I really hope someone can help
me.
------------ USER.PM -------------
#!/usr/bin/perl -w
use strict;
package user;
sub new
{
my ($class_name) = @_;
my ($self) = {};
#warn "We just created our new variable...\n ";
bless ($self, $class_name);
#warn "and now it's a $class_name object!\n";
#$self->{'_created'} = 1;
return $self;
}
sub getId
{
my $self = shift;
return $self->{'id'};
}
sub setId
{
my ($self, $id) = @_;
$self->{'id'} = $id;
}
sub getUsername
{
my $self = shift;
return $self->{'username'};
}
sub setUsername
{
my ($self, $username) = @_;
$self->{'username'} = $username;
}
sub getPassword
{
my $self = shift;
return $self->{'password'};
}
sub setPassword
{
my ($self, $password) = @_;
$self->{'password'} = $password;
}
sub getSessionKey
{
my $self = shift;
return $self->{'sessionkey'};
}
sub setSessionKey
{
my ($self, $key) = @_;
$self->{'sessionkey'} = $key;
}
1;
-------- USER_MANAGEMENT.PM ------------------
#!/usr/bin/perl -w
package user_management;
use user;
use strict;
#my $instance = new user_management;
sub new
{
my ($class_name) = @_;
my ($self) = {};
bless ($self, $class_name);
#some objects for the array
my $phill = new user;
$phill->setId(6);
$phill->setUsername("ptaylor");
$phill->setPassword("password");
$phill->setSessionKey("");
my $simon = new user;
$simon->setId(7);
$simon->setUsername("sroberts");
$simon->setPassword("cheese");
$simon->setSessionKey("");
my $nick = new user;
$nick->setId(8);
$nick->setUsername("nick");
$nick->setPassword("rock");
$nick->setSessionKey("");
#put them in the array
my @users = ( $phill, $simon, $nick );
$self->{users} = \@users; #put the array in an instance variable (or
perl equiv)
$self->{nextSessionId} = ":-0";
return $self;
}
sub login
{
my ($self, $username, $password) = @_;
my @users = @{ $self->{users} };
foreach my $user (@users)
{
if ($user->getUsername() eq $username)
{
if ($user->getPassword() eq $password)
{
if ($user->getSessionKey ne "")
{
return "ERR: User already logged in";
}
else
{
#generate session key
$user->setSessionKey("SESS" . $self->{'nextSessionId'});
$self->{'nextSessionId'} = $self->{'nextSessionId'} + 1;
return $user->getSessionKey();
}
}
else
{ return "ERR: Password is wrong"; }
}
}
return "ERR: No users";
}
sub query
{
my $self = shift;
#return "Session id= " . $self->{nextSessionId} . "\n";
my @users = @{$self->{users}};
my $active = 0;
my $total = @users;
my $retval = "";
#return "Total: $total\n";
foreach my $usr (@users)
{
bless($usr, "user");
if ($usr->getSessionKey() ne "")
{
$retval = $retval . "user " . $usr->getUsername() . " logged in\n";
$active++;
}
else
{
$retval = $retval . "user " . $usr->getUsername() . " logged out
\n";
}
}
return "$retval$active of $total";
}
sub logout
{
my ($self, $sessionKey) = @_;
my @users = @{ $self->{users} };
foreach my $usr (@users)
{
if ($usr->getSessionKey() eq $sessionKey)
{
$usr->setSessionKey("");
return 1;
}
}
return 0;
}
1;
------------ TEST_USER.PL ----------------------------------
#!/usr/bin/perl -w
#THIS SCRIPT TESTS THAT USER_MANAGEMENT.PM WORKS CORRECTLY
#IT DOES WORK CORRECT ACCORDING TO THIS SCRIPT!
use user;
use user_management;
use strict;
print "code started\n";
my $phill1 = new user;
$phill1->setId(6);
$phill1->setUsername("phill");
$phill1->setPassword("hello");
my $dave1 = new user;
$dave1->setId(7);
$dave1->setUsername("dave");
$dave1->setPassword("omg");
my $alan1 = new user;
$alan1->setId(8);
$alan1->setUsername("alan");
$alan1->setPassword("alsecret");
my @users = ( $phill1, $alan1, $dave1 );
foreach my $currentUser (@users)
{
print "user id:\t" . $currentUser->getId() . "\n";
print "username:\t" . $currentUser->getUsername() . "\n";
print "password:\t" . $currentUser->getPassword() . "\n";
}
print "done\n";
#&load;
my $sessionKey = login("ptaylor","password");
print $sessionKey;
my $answer = &query;
print "$answer\n";
logout ($sessionKey);
$answer = &query;
print "$answer\n";
$sessionKey = login("nick","rock");
print "session key for nick is $sessionKey\n";
$answer = &query;
print "$answer\n";
print "done\n";
------------ USER_MANAGEMENT.CGI ----------------------
#!/usr/bin/perl -w
package user_management;
use user_management;
no warnings;
use SOAP::Transport::HTTP;
SOAP::Transport::HTTP::CGI
-> dispatch_to('user_management')
-> handle;
------------ THE WSDL FILE ----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="user_management"
targetNamespace="**textdeleted**"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="**textdeleted**"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<message name="loginParams">
<part name="username" type="xsd:string" />
<part name="password" type="xsd:string" />
</message>
<message name="loginRetval">
<part name="retval" type="xsd:string" />
</message>
<message name="void">
</message>
<message name="queryRetval">
<part name="retval" type="xsd:string" />
</message>
<message name="logoutParams">
<part name="sessionKey" type="xsd:string" />
</message>
<message name="logoutRetval">
<part name="retval" type="xsd:int" />
</message>
<portType name="user_management_port_type">
<operation name="login">
<input message="tns:loginParams" />
<output message="tns:loginRetval" />
</operation>
<operation name="query">
<input message="tns:void" />
<output message="tns:queryRetval" />
</operation>
<operation name="logout">
<input message="tns:logoutParams" />
<output message="tns:logoutRetval" />
</operation>
</portType>
<binding name="user_management_binding"
type="tns:user_management_port_type">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/
http" />
<operation name="login">
<soap:operation soapAction="urn:user_management#login" />
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</output>
</operation>
<operation name="query">
<soap:operation soapAction="urn:user_management#query" />
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</output>
</operation>
<operation name="logout">
<soap:operation soapAction="urn:user_management#logout" />
<input>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</input>
<output>
<soap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:user_management"
use="encoded" />
</output>
</operation>
</binding>
<service name="UserManagementService">
<documentation>Session Management for AM</documentation>
<port binding="tns:user_management_binding"
name="user_management_port">
<soap:address
location="**textdeleted**/user_management.cgi" />
</port>
</service>
</definitions>
-------------- THE SOAP CLIENT -------------------------
'consists of a textbox and a button of the window.
Imports SessionManagementExample.UserManagement
Public Class Form1
Private server As UserManagementService
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
server = New UserManagementService()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Dim answer As String = server.query()
TextBox1.Text = answer.Replace(Chr(10), vbCrLf)
End Sub
End Class
------------------------------------------------
Any help would be really appreciated. Thanks
> ------------ USER_MANAGEMENT.CGI ----------------------
> #!/usr/bin/perl -w
>
> package user_management;
>
> use user_management;
> no warnings;
> use SOAP::Transport::HTTP;
>
> SOAP::Transport::HTTP::CGI
> -> dispatch_to('user_management')
> -> handle;
Nice, the SOAP and SOAP-Lite distributions uses the same package names
but with quite different documented API's, and you're using the
SOAP-Lite version it seems.
It is documented that you can use a module name as argument to
dispatch_to, but this doesn't mean that it instantiates an object and
calls the methods on this object. Instead it uses the methods as class
methods, in which case you $self variable will contain the class name
and not an instantiated object.
This is consistent with you seeing it complaining about trying to use
'user_magement' as a HASH ref, bacause this is what $self will be when
the methods is called as class methods.
A possible solution would be to have you cgi script say something
along the lines of:
#!/usr/bin/perl
use strict;
use warnings;
use user_management;
use SOAP::Transport::HTTP; # SOAP Lite module!!!
my $manager = user_management->new();
SOAP::Transport::HTTP::CGI->dispatch_to($manager)
->handle;
__END__
Even though this isn't quite as documented in SOAP::Transport::HTTP,
but see http://search.cpan.org/perldoc?SOAP::Server
//Makholm
> Nice, the SOAP and SOAP-Lite distributions uses the same package names
> but with quite different documented API's, and you're using the
> SOAP-Lite version it seems.
The SOAP distribution seems unmaintained since september 2000 and
SOAP-Lite have lots of releases sinces this time.
//Makholm
Oh wow it works perfectly.
Thank you Peter I really appreciate the time you've taken to answer my
post. :-)
it's called heuristics.
> A. Sinan Unur wrote:
>> Philluminati <Phillip.R...@gmail.com> wrote in news:661262f3-
>> aea5-4734-906...@m44g2000hsc.googlegroups.com:
>>
>>> my @users = ref $self->{'users'}; //same message as above
>>> my @users = @$self->{'users'};
>>> my @users = \$self->{'users'};
>>> my @users = map $self->{'users'}; //gave 500 internal server err
>>> my @users = ( $self->{'users'} ); //same as original err
>>> my @users = scalar $self->{'users'};
>>
>> You are ignoring the fact that programming is a deterministic
>> endeavor. Successful programmers are not those who throw a bazillion
>> variations at a wall and see what sticks.
>
> Isn't also about trial and error? Especially, but not limited to,
> people who are young in this field of study? How does one learn
> something if they do not run some tests?
A test, or maybe better: an experiment, is not the same as
adding/removing code until it works. It's understanding each ingredient
because you have studied the documentation, and it's having an
expectation of the outcome, and the code is to verify if your
understanding of the documentation is corrent.
Trial and error (try all and error), is often: put a book on your lap
(or nowadays open a browser), find a snippet of code that seems right,
and start modifying it until it works.
Somehow people think that actually reading a book has nothing to do with
programming (or that it's the long road), that programming is pressing
keys and nothing else. And no, I am not talking about managers.
But some people claim they can't read a book, and/or that they are more
practical and/or that their "way" works faster. They somehow forget that
people who are practical, for example a carpenter, don't trial and
error. A carpenter is not going to cut wood up into pieces and trying
all possible ways to stick them together in order to make a table. Such
a carpenter wood run out of resources very fast.
But somehow, as a "programmer" you're only wasting time, so it's harder
to detect, especially if the "programmer" is pushing keys the whole day.
( They also forget that it's quite hard to remember the solution if it
was found by trying a lot of possibilities. The next time they have a
similar problem they only vaguely remember what they did the last time,
and have to start somewhere at the beginning, modifying code again. )
> That is more or less how I advanced so deep
> into programming many moons ago, trying to see if this works,
You could have read that in the documentation. Something works or it
doesn't. There is no sometimes.
> what this
> that do, what happens if I do this, etc. Albeit, one should keep
> documentation close by too, but trial and error *is* a as big a part
> as anything IMHO.
It sounds to me that you talk more about what I call experimentation.
Trial and error is banging your head against the wall without having
read that there is a better tool to make a hole into it.
What's so sad, nowadays, is a lot of code discovered that way ends up on
the Internet, and is copied by trial and error programmers...
( I have similar feelings about people grabbing for a debugger for each
and every problem. I once worked on a project in a company, using C, and
each and every time there was a problem the way of action was to fire up
a debugger and single step throught the code.).
--
John
That reminds me, I need to buy more tape.
--
Lawrence Statton - lawre...@abaluon.abaom s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
place them into the correct order.
While I agree with that completely, I have to concede that the syntax
for dereferencing in perl is somewhat arcane. I remember reading perldoc
perlref 10+ years ago, scratching my head and wondering what the fuck
Larry was smoking. And I probably did throw a bazillion of variations at
the compiler until I finally figured out that it's really quite simple.
>> All I want to do is pull that array back into a variable. Anyone?
>
> If $x is a reference to an array, then @{ $x } dereferences it.
>
> my @users = @{ $self->{users} };
Yup. That's one of the two rules to remember. The other is to use -> to
access individual members.
hp
The "camel book" probably isn't the best book to learn perl. It is
intended as a reference, not a tutorial. The "llama book", Learning
Perl, Fourth Edition, by Randal L. Schwartz, Tom Phoenix, brian d foy,
is generally recommended for beginners. Or you can just read the
documentation that comes with perl (I learned Perl that way, although I
think I might have figured out some things faster if I had read the
O'Reilly books) or one of the gazillion other books about perl (although
Sturgeon's law applies to Perl books just as to SF novels).
As for the "funny lines of code": Fun is for me an intrinsic part of the
Perl culture. You may or may not appreciate Larry's sense of humor or
writing style, but if you don't enjoy playing with a language, Perl
probably isn't the language of your choice.
> Look I know I am going to have to read the book no matter how much of
> a frustrating read it is. However I do want to get this prototype
> running prior to my intellectual investment. I don't want to read 900
> pages when effectively the prototype I'm writing is going to say
> whether the language is feasible or not, not my willingness or
> unwillingness to learn it.
You won't know whether Perl is feasible for some (reasonably complex)
task until you know it fairly well. Hacking together a few lines of code
without understanding the language won't tell you that. If you do
succeed in writing a few lines, you still won't know if it is well
suited to more complex tasks. And when you don't succeed all you know is
that you haven't learned enough. Perl is a general purpose programming
language. You can write anything in Perl. But for some tasks, other
languages are better suited.
hp
PS: I recommend to read this: http://www.norvig.com/21-days.html
I'm currently considering writing a module that would allow the syntax
my @users = $self->{users}[];
instead[1]. Given that it will be rather tricky, would people actually
find such a thing useful, or would the 'effort' of loading a module be
enough to put people off using it?
Ben
[1] I originally did it as a patch for core perl, which was considerably
easier; the consensus on p5p was that such minor and not-obviously-
terribly-useful syntax changes should be tested on CPAN first, if at all
possible.
--
I've seen things you people wouldn't believe: attack ships on fire off
the shoulder of Orion; I watched C-beams glitter in the dark near the
Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
Time to die. b...@morrow.me.uk
The module would have to be based on something like Filter::Util::Call,
right? I've heard bad things about the stability of that, which would put
me off using such a module on a regular basis. Other than that, I'd like
it very much.
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Source filters that try to heuristically parse Perl, or something like
it, (Switch being the canonical example) are typically unreliable, since
it's essentially impossible to parse Perl except by running it through
perl and looking at the resulting optree. Even PPI (a newish Perl module
that almost-perfectly parses Perl) isn't good enough, as there are cases
that simply cannot be parsed correctly without actually running the
code.
There are two ways I can see to avoid this. Devel::Declare gets around
the issue by (extremely hackishly) inserting hooks into the real parser,
which can then parse a short section of new syntax and return control.
While this has the advantage of using the real parser to parse
everything that isn't the new syntax, I'm not sure it can be done in
this case: I suspect the 'Syntax error' case fires too soon.
The alternative would be to ship my modified versions of toke.c and
perly.y (and derived files) with the module. This way I can compile
copies of yylex() and yyparse() that are actually correct, and still
call the functions in op.c to build the optree. Then I should be able to
install this parser as a source filter (in this case, one that simply
builds an optree and doesn't return any text to the 'real' parser, much
like ByteLoader) while avoiding the heuristics that usually make them so
unreliable.
> Other than that, I'd like it very much.
OK, cool. As you can see, it's quite a bit of work, so I'm not making
any promises :).
Ben
--
Raise your hand if you're invulnerable.
[b...@morrow.me.uk]
Nice. Is there a way to extend this to array slices?
my @users = $self->{users}[1, 3 .. 5]
But I guess that collides with existing valid syntax.
> Given that it will be rather tricky, would people actually
> find such a thing useful, or would the 'effort' of loading a module be
> enough to put people off using it?
>
> Ben
>
> [1] I originally did it as a patch for core perl, which was considerably
> easier; the consensus on p5p was that such minor and not-obviously-
> terribly-useful syntax changes should be tested on CPAN first, if at all
> possible.
I would find that very useful. The effort of loading a module wouldn't
put me off, instabilities introduces by a source-filter might, though.
hp
> Oh wow it works perfectly.
>
> Thank you Peter I really appreciate the time you've taken to answer my
> post. :-)
Note that it took less than an hour from you posted the right pieces
of code till you got an working answer. Before you posted the code
where you actually uses you package to get the error nobody would be
able to help without making som wild assumptions about what you were
doing.
Posting a complete minimal example showing you problem would have
helped you from the first post.
//Makholm