using real objects in constructors

Discussion in 'Perl Misc' started by Rainer Weikusat, Mar 4, 2014.

  1. 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?
     
    Rainer Weikusat, Mar 4, 2014
    #1
    1. Advertisements

  2. Rainer Weikusat

    Jim Gibson Guest

    Couldn't you also do this, then:

    sub new
    {
    my ($class, $arg) = @_;
    return bless([$arg], $class);
    }
     
    Jim Gibson, Mar 5, 2014
    #2
    1. Advertisements

  3. Rainer Weikusat

    Tim McDaniel Guest

    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.)
     
    Tim McDaniel, Mar 5, 2014
    #3
  4. Rainer Weikusat

    Tim McDaniel Guest

    But
    sub new{bless@_[1,0]}
    saves 9 precious characters.
     
    Tim McDaniel, Mar 5, 2014
    #4
  5. 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.
     
    Rainer Weikusat, Mar 5, 2014
    #5
  6. I'd be extremely wary bestowing a blessing on something a stranger
    passed to me without even looking at it ...
     
    Rainer Weikusat, Mar 5, 2014
    #6
  7. Rainer Weikusat

    John Bokma Guest

    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.
     
    John Bokma, Mar 5, 2014
    #7
  8. 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?
    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.
     
    Rainer Weikusat, Mar 5, 2014
    #8
  9. Rainer Weikusat

    C.DeRykus Guest

    ....


    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;
     
    C.DeRykus, Mar 5, 2014
    #9
  10. 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).
     
    Rainer Weikusat, Mar 5, 2014
    #10
  11. '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.
     
    Rainer Weikusat, Mar 5, 2014
    #11
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.