Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Trying to understand a constructor with an array.

Reply
Thread Tools

Trying to understand a constructor with an array.

 
 
Overt
Guest
Posts: n/a
 
      08-07-2008
Don't anybody laugh. I am trying to learn Object Perl and modifying
examples in the books just to understand what is going on.

Here is a simple object creation where I am using an array rather than a
hash.

Called with this -
my @tarray;
$tarray[0][0] = 1;
$tarray[0][1] = 2;
$tarray[1][0] = 3;
$tarray[1][1] = 4;
my $displayobj = Display->new(\@tarray);

Here is the constructor -
sub new {
my $class = shift;
my $self = [];
$self->[@_] = shift;
bless($self, $class);
$DB::single = 1; #this is where I examine $self
return $self;
}

It works ok, but $self contains an array of an array, rather than just a 2
dimentional array. Like so
$self[0][0][0] = [1]
$self[0][0][1] = [2]
$self[0][1][0] = [3]
$self[0][1][1] = [4]

Why an array of an array, rather than just an array?

Again, this isn't a problem I am trying to fix, just something I am trying
to understand.

Thanx anybody
Overt
 
Reply With Quote
 
 
 
 
Leon Timmermans
Guest
Posts: n/a
 
      08-07-2008
On Thu, 07 Aug 2008 17:59:56 +0200, Overt wrote:

> Don't anybody laugh. I am trying to learn Object Perl and modifying
> examples in the books just to understand what is going on.
>
> Here is a simple object creation where I am using an array rather than a
> hash.
>
> Called with this -
> my @tarray;
> $tarray[0][0] = 1;
> $tarray[0][1] = 2;
> $tarray[1][0] = 3;
> $tarray[1][1] = 4;
> my $displayobj = Display->new(\@tarray);
>


How about

my $displayobj = Display->new([ [1, 2], [3, 4] ]);

> $self->[@_] = shift;


This line doesn't make sense to me at all.

> It works ok, but $self contains an array of an array, rather than just a
> 2 dimentional array. Like so
> $self[0][0][0] = [1]
> $self[0][0][1] = [2]
> $self[0][1][0] = [3]
> $self[0][1][1] = [4]
>
> Why an array of an array, rather than just an array?
>


I think what you want to do is:

my $self = [ @{+shift} ];

Regards,

Leon Timmermans
 
Reply With Quote
 
 
 
 
xhoster@gmail.com
Guest
Posts: n/a
 
      08-07-2008
Overt <(E-Mail Removed)> wrote:
> sub new {
> my $class = shift;
> my $self = [];
> $self->[@_] = shift;


>
> It works ok, but $self contains an array of an array, rather than just a
> 2 dimentional array. Like so
> $self[0][0][0] = [1]
> $self[0][0][1] = [2]
> $self[0][1][0] = [3]
> $self[0][1][1] = [4]


Surely not. $self->[0][0][0]=1;

>
> Why an array of an array, rather than just an array?


new is called with @_ containing two things. Both of those things
get shifted off, leaving @_ with zero things. Array subscripts,
like the @_ in "$self->[@_]", are evaluated in scalar context, and in a
scalar context arrays yield the number of elements, which is zero. So your
code is equivalent to:

$self->[0] = shift;

(The reason you get 0 rather than 1 is that the right hand side of the
assignment is evaluated first, so by the time @_ is evaluated in scalar
context on the left hand side, it has already been shifted.)

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.
 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      08-07-2008
On 2008-08-07 16:34, Leon Timmermans <(E-Mail Removed)> wrote:
> On Thu, 07 Aug 2008 17:59:56 +0200, Overt wrote:
>
>> Here is a simple object creation where I am using an array rather than a
>> hash.
>>
>> Called with this -
>> my @tarray;
>> $tarray[0][0] = 1;
>> $tarray[0][1] = 2;
>> $tarray[1][0] = 3;
>> $tarray[1][1] = 4;
>> my $displayobj = Display->new(\@tarray);
>>

>
> How about
>
> my $displayobj = Display->new([ [1, 2], [3, 4] ]);
>
>> $self->[@_] = shift;

>
> This line doesn't make sense to me at all.


This is tricky: shift modifies @_, so is the length of @_, which is used
as an index, taken before or after the shift? We know that the length is
1 before and 0 after the shift, so that might be equivalent to

$self->[0] = shift;

or to

$self->[1] = shift;

or it might even be completely undefined. Apparently, the shift is
evaluated first, so it's equivalent to $self->[0] = shift; But if the OP
meant that he should have written it instead of relying on an
unspecified evaluation order, and anyway I doubt that he meant it. But I
wonder what the thought that this would do.


>> It works ok, but $self contains an array of an array, rather than just a
>> 2 dimentional array. Like so
>> $self[0][0][0] = [1]
>> $self[0][0][1] = [2]
>> $self[0][1][0] = [3]
>> $self[0][1][1] = [4]
>>
>> Why an array of an array, rather than just an array?
>>

>
> I think what you want to do is:
>
> my $self = [ @{+shift} ];


Or

$self = shift;

which is subtly different.

hp
 
Reply With Quote
 
Leon Timmermans
Guest
Posts: n/a
 
      08-07-2008
On Thu, 07 Aug 2008 20:36:28 +0200, Peter J. Holzer wrote:

> On 2008-08-07 16:34, Leon Timmermans <(E-Mail Removed)> wrote:
> But I wonder what the thought that this would do.


Yeah, that's what I meant.

> Or
>
> $self = shift;
>
> which is subtly different.
>


Yeah, but personally I'd by wary of blessing anything I didn't create
myself, that can bite one in unexpected ways.

Leon Timmermans
 
Reply With Quote
 
Michael Carman
Guest
Posts: n/a
 
      08-09-2008
Overt wrote:
>>
>> my $self = [ @{+shift} ];

>
> I would not have discovered it on my own (at least for a long while),
> because I can't find that construction in any of my documentation.


That's probably because it's not one construct but several written together:

* The [...] creates a reference to an anonymous array. This is what
gets assigned to $self.
* The @{...} is an array dereference.
* The shift() function removes and returns the first element from an
array. If no array is specified (and you're inside a subroutine) it
operates on @_.
* @_ is the array used to pass arguments to subs.
* The + is the unary sign operator. It forces the "shift" to be
interpreted as a function call instead of as a bareword. Without it
the expression would parse as the array @shift instead of as
@{ shift(@_) }

Personally, I wouldn't write it this way, because I think it's very
obscure. I would write

my $self = shift;

as Peter suggested. You could add a check for C<ref($self) eq 'ARRAY'>
if you share Leon's concern and want to ensure that the user didn't pass
in the wrong thing as an argument.

> I am just a hobbyist programmer (so far), but where do you learn this
> type of info?


The best way to learn is by doing. Keep programming and keep learning
new things as you go. I learned gobs of Perl by lurking in this
newsgroup. Read the docs. Read (good) books. Whenever you see something
new, try to understand it and think of how and where you might use it.
Go back to your old code and rewrite it as you learn new and better idioms.

> I keep tripping across neat stuff like the above and wonder just how
> many zillions of other good items that I will never learn and can't
> use because I don't know they exist.


I don't know. I've been using Perl for more than a decade and I still
learn new things occasionally. There are some dusty corners that I've
never really had a reason to explore.

> Possibly you went to a professional school to learn.


Some of the people here have had a formal education in computer science,
but I don't think many have had formal schooling in Perl. There are
training courses though, and many of the more prominent posters here
teach them.

-mjc
 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      08-11-2008
On 2008-08-09 03:32, Michael Carman <(E-Mail Removed)> wrote:
> Overt wrote:
>>> my $self = [ @{+shift} ];

>>
>> I would not have discovered it on my own (at least for a long while),
>> because I can't find that construction in any of my documentation.

>
> That's probably because it's not one construct but several written together:
>
> * The [...] creates a reference to an anonymous array. This is what
> gets assigned to $self.
> * The @{...} is an array dereference.
> * The shift() function removes and returns the first element from an
> array. If no array is specified (and you're inside a subroutine) it
> operates on @_.
> * @_ is the array used to pass arguments to subs.
> * The + is the unary sign operator. It forces the "shift" to be
> interpreted as a function call instead of as a bareword. Without it
> the expression would parse as the array @shift instead of as
> @{ shift(@_) }
>
> Personally, I wouldn't write it this way, because I think it's very
> obscure. I would write
>
> my $self = shift;
>
> as Peter suggested.


So I did. But I've been very brief because I wanted to tease the OP into
trying to find out what the subtle difference is. Probably too brief - I
don't think I succeeded.

As a matter of style, I vastly prefer

sub new {
my ($class, $data) = @_;
...
}

over

sub new {
my $class = shift;
my $data = shift;
...
}

especially if the second shift would be hidden in a complex expression
and not be immediately visible to the reader (I sometimes do use shift
(or even pop) to deal with optional arguments).

So that constructor would become:

sub new {
my ($class, $data) = @_;

my $self = $data;
bless $self, $class;
return $self;
}

or, if I wanted to copy the elements of @$data to @$self (and avoid
accidentally blessing $data):

sub new {
my ($class, $data) = @_;

my $self = [ @$data ];
bless $self, $class;
return $self;
}



> You could add a check for C<ref($self) eq 'ARRAY'>
> if you share Leon's concern and want to ensure that the user didn't pass
> in the wrong thing as an argument.


Yup. Since perl cannot check types at compile time it is often a good
idea to add such checks at run time.

hp
 
Reply With Quote
 
Ben Morrow
Guest
Posts: n/a
 
      08-12-2008

Quoth Overt <(E-Mail Removed)>:
>
> It is just my opinion, but complex expressions are for production code.
> Tutorial examples of code should have one function per line so that the
> learner can easily decode what the code is doing. The production programmer
> can always pack the stuff together if wanted.


I would disagree here: production code should *also* be written as
clearly as possible. It is even more important in that case that the
code be comprehensible: at least when working through a tutorial you
have the luxury of spending as much time as you need figuring things
out.

OTOH, composing expressions doesn't necessarily make them more complex.
One of the problems with languages like C is that the code ends up so
spread out it's difficult to see the flow of the logic: you end up being
unable to see the wood for the trees.

> Even with functions I am familiar with, I usually leave them broken apart
> just so that months later I can tell at a glance what I was trying to do.


Good. You should always think about how the code will read to someone
coming to it for the first time.

Ben

--
It will be seen that the Erwhonians are a meek and long-suffering people,
easily led by the nose, and quick to offer up common sense at the shrine of
logic, when a philosopher convinces them that their institutions are not based
on the strictest morality. [Samuel Butler, paraphrased] http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dont understand constructor... Sreenivas Java 7 12-21-2007 03:32 AM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
unable to understand constructor behavior neo C++ 4 12-30-2006 12:00 AM
Read all of this to understand how it works. then check around on otherRead all of this to understand how it works. then check around on other thelisa martin Computer Support 2 08-18-2005 06:40 AM
Trying to Understand Layer 2 scadav Cisco 6 07-07-2005 05:24 PM



Advertisments