using real objects in constructors

  • Thread starter Rainer Weikusat
  • Start date
R

Rainer Weikusat

The usual way to construct an instance of a Perl class (I'm aware of)
would look somewhat like this:

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

$self->[0] = $arg;
return bless($self, $class);
}

Fairly recently, it occured to me that this can also be accomplished
with

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

$self[0] = $arg;
return bless(\@self, $class);
}

Are there any good (or not-so-good) reasons to prefer one over the
other?
 
J

Jim Gibson

Rainer said:
The usual way to construct an instance of a Perl class (I'm aware of)
would look somewhat like this:

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

$self->[0] = $arg;
return bless($self, $class);
}

Fairly recently, it occured to me that this can also be accomplished
with

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

$self[0] = $arg;
return bless(\@self, $class);
}

Are there any good (or not-so-good) reasons to prefer one over the
other?

Couldn't you also do this, then:

sub new
{
my ($class, $arg) = @_;
return bless([$arg], $class);
}
 
T

Tim McDaniel

Rainer said:
The usual way to construct an instance of a Perl class (I'm aware of)
would look somewhat like this:

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

$self->[0] = $arg;
return bless($self, $class);
}

Fairly recently, it occured to me that this can also be accomplished
with

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

$self[0] = $arg;
return bless(\@self, $class);
}

Are there any good (or not-so-good) reasons to prefer one over the
other?

Couldn't you also do this, then:

sub new
{
my ($class, $arg) = @_;
return bless([$arg], $class);
}

so

sub new{bless [$_[1]],$_[0]}

?

(My first thought was "sub new{bless [pop],pop}", but that only
works if there are exactly two arguments.)
 
T

Tim McDaniel

Quoth (e-mail address removed):
Couldn't you also do this, then:

sub new
{
my ($class, $arg) = @_;
return bless([$arg], $class);
}

so
sub new{bless [$_[1]],$_[0]}
?

The nearest thing to a 'standard' Perl constructor would be
sub new { bless $_[1], $_[0] }
It takes a hashref of attributes and turns it into an object.

But
sub new{bless@_[1,0]}
saves 9 precious characters.
 
R

Rainer Weikusat

Jim Gibson said:
Weikusat said:
The usual way to construct an instance of a Perl class (I'm aware of)
would look somewhat like this:

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

$self->[0] = $arg;
return bless($self, $class);
}

Fairly recently, it occured to me that this can also be accomplished
with

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

$self[0] = $arg;
return bless(\@self, $class);
}

Are there any good (or not-so-good) reasons to prefer one over the
other?

Couldn't you also do this, then:

sub new
{
my ($class, $arg) = @_;
return bless([$arg], $class);
}

Obviously. But that's a variant of the first subroutine quoted above as
it uses an anonymous array. And for a real object, I wouldn't be using

$self[0] = ...

but

$self[ARGN] = ...

with some sensible attribute name instead of ARGN and usually leave the
allocation of array indices/ slots for attribute names to other
code. It's just that "Run to the hills --- arrows everywhere!",


isn't something I'm necessarily fond of because of iself.
 
R

Rainer Weikusat

Ben Morrow said:
Quoth (e-mail address removed):
Couldn't you also do this, then:

sub new
{
my ($class, $arg) = @_;
return bless([$arg], $class);
}

so

sub new{bless [$_[1]],$_[0]}

The nearest thing to a 'standard' Perl constructor would be

sub new { bless $_[1], $_[0] }

I'd be extremely wary bestowing a blessing on something a stranger
passed to me without even looking at it ...
 
J

John Bokma

Henry Law said:
I'm very confused, watching my betters arguing over what (to me) looks
like the hairstyles of the angels on the head of the pin.

What's the matter with the "usual way" which Rainer starts with? If
it's the usual way, then surely out of deference to whoever is to
maintain your code, it's the way you should do it?

I think it boils down to using:

my @array = ( 'bar' );
$array[ 1 ] = 'foo';

...

return \@array;

v.s.

my $aref = [ 'bar' ];
$aref->[ 1 ] = 'foo';

...

return $aref;


Which one I use depends on how noisy the rest of the code gets, e.g.


$array[] v.s $aref->[]

and

for ( @array ) v.s. for ( @$aref )

and

baz( \@array ) v.s. baz( $aref )

( Same can be written for %hash v.s. $href).

To me, there's no usual way. And I think it's a must for Perl
programmers to understand both.
 
R

Rainer Weikusat

Henry Law said:
I'm very confused, watching my betters arguing over what (to me) looks
like the hairstyles of the angels on the head of the pin.

Quoting an actual example:

sub new
{
my ($class, $rq, $one_time, $title, $valid_for, $url_prefix, $secrets) = @_;
my @self;

$self[RQ] = $rq;
$self[ONE_TIME] = $one_time;
$self[TITLE] = $title;
$self[VALID_FOR] = $valid_for;
$self[URL_PREFIX] = $url_prefix;
$self[SECRETS] = $secrets;

return bless(\@self, $class);
}

Using an anonymous array, this would become

sub new
{
my ($class, $rq, $one_time, $title, $valid_for, $url_prefix, $secrets) = @_;
my $self;

$self->[RQ] = $rq;
$self->[ONE_TIME] = $one_time;
$self->[TITLE] = $title;
$self->[VALID_FOR] = $valid_for;
$self->[URL_PREFIX] = $url_prefix;
$self->[SECRETS] = $secrets;

return bless($self, $class);
}

Is there something tangible I'd get in return for typing -> -> -> -> ->
->? At the moment, I don't think so. So why do it?
What's the matter with the "usual way" which Rainer starts with? If
it's the usual way, then surely out of deference to whoever is to
maintain your code, it's the way you should do it?

I have no way of knowing anything about the preferences of somebody who
might have to make modifications to this code in future, however, right
now, I am this someone and I prefer not dealing with redundant
punctuation: If it is in the code, then because I'm convinced that it is
good for something (or was convinced that it was good for something by
the time I wrote it) and if I'm not, then, it won't be.
 
C

C.DeRykus

Henry Law said:
I'm very confused, watching my betters arguing over what (to me) looks
like the hairstyles of the angels on the head of the pin.

Quoting an actual example:

sub new
{
my ($class, $rq, $one_time, $title, $valid_for, $url_prefix, $secrets) = @_;
my @self;
$self[RQ] = $rq;
$self[ONE_TIME] = $one_time;
$self[TITLE] = $title;
$self[VALID_FOR] = $valid_for;
$self[URL_PREFIX] = $url_prefix;
$self[SECRETS] = $secrets;
return bless(\@self, $class);
}
....


Side issue: maybe a more de-cluttered
hairstyle will suit tiny dance floors:

my $class = shift @_;
my @self;
@self[RQ, ONE_TIME, TITLE, VALID_FOR_URL,
URL_PREFIX, SECRETS] = @_;

bless \@self, $class;
 
R

Rainer Weikusat

C.DeRykus said:
]
sub new
{
my ($class, $rq, $one_time, $title, $valid_for, $url_prefix, $secrets) = @_;
my @self;
$self[RQ] = $rq;
$self[ONE_TIME] = $one_time;
$self[TITLE] = $title;
$self[VALID_FOR] = $valid_for;
$self[URL_PREFIX] = $url_prefix;
$self[SECRETS] = $secrets;
return bless(\@self, $class);
}
...


Side issue: maybe a more de-cluttered
hairstyle will suit tiny dance floors:

my $class = shift @_;
my @self;
@self[RQ, ONE_TIME, TITLE, VALID_FOR_URL,
URL_PREFIX, SECRETS] = @_;

bless \@self, $class;

This is somewhat maintenance-unfriendly, as evidenced by the appearance
of a 'valid for url' attribute (the argument assignment line
has exactly the same problem, though).
 
R

Rainer Weikusat

Ben Morrow said:
Quoth Henry Law said:
On 04/03/14 17:18, Rainer Weikusat wrote:
[...]
What's the matter with the "usual way" which Rainer starts with? If
it's the usual way, then surely out of deference to whoever is to
maintain your code, it's the way you should do it?

Well, using arrayrefs for objects is not 'usual' in any sense, but
that's a whole different question.

'Usual' was here supposed to refer to 'creating an anonymous object' vs
'returning a reference to a non-anonymous one'. It is also 'usual' that
people abuse hashes in order to emulate 'records'/ 'C structs' because
this seems to be the path of least resistance for creating a 'complex'
object with individual fields which can be accessed by name (which is
then 'usually' not done in favour of wrapping another layer of hashing
around that).

It is not a very good choice for that, however, as there's no
immediateley obvious way of sharing a container object among related
classes while continuing to use 'convenient' attribute names because the
hash provides as a 'flat' 'global namespace', because hashes need more
memory than arrays to store the same number of attributes, because
attribute accesses require run-time hash lookups and because these
accesses usually can't be checked by a compiler.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top