stevieb has asked for the wisdom of the Perl Monks concerning the following question:

Reviewing some of my code, and I'm wondering if and how the Monks would write these rw accessors to make them more concise (ie. more compact, without using external modules). Bonus points for a solution that uses a single routine to cover both, but is easy to an experienced Perl dev to look at in six months and immediately identify without any question what's happening.

sub ip { my ($self, $ip) = @_; return $self->{ip} if $self->{ip}; if (! $ip && $self->{conf}{ip}){ $ip = $self->{conf}{ip}; } $ip = '0.0.0.0' if ! $ip; $self->{ip} = $ip; } sub port { my ($self, $port) = @_; return $self->{port} if $self->{port}; if (! $port && $self->{conf}{port}){ $port = $self->{conf}{port}; } $port = '7800' if ! defined $port; $self->{port} = $port; }

{conf} is simply an element from an ini-style config file, which may not be available, and that would make the statement untrue.

I'm taking off camping in the mountains in the AM, so I'll review any replies when I return on Monday.

Replies are listed 'Best First'.
Re: More concise way to write these accessors?
by BrowserUk (Patriarch) on Jun 25, 2016 at 04:10 UTC

    Those are weird rw accessors. If the object already has an internal value for this field, ignore any value the user is attempting to set and return the existing value?

    But:

    sub ip { $_[0]->{ip} //= $_[1] // $_[0]->{conf}{ip} // '0.0.0.0' +} sub port{ $_[0]->{port} //= $_[1] // $_[0]->{conf}{port} // '7800' +}

    Or:

    eval <<EOA for [ 'ip', '0.0.0.0' ], [ 'port', '7800' ]; sub $_->[0] { \$_[0]->{$_->[0]} //= \$_[1] // \$_[0]->{conf}{$_->[0]} +// \"$_->[1]\" } EOA

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
Re: More concise way to write these accessors?
by $h4X4_&#124;=73}{ (Monk) on Jun 25, 2016 at 08:12 UTC

    I think this looks a little better. You will have to test it to see if it works for you.

    sub ip { my $self = shift; my $ip = shift || '0.0.0.0'; $self->{ip} = ($ip eq '0.0.0.0' && $self->{conf}{ip}) ? $self->{conf}{ip} : $ip; return $self->{ip}; } sub port { my $self = shift; my $port = shift || '7800'; $self->{port} = ($port eq '7800' && $self->{conf}{port}) ? $self->{conf}{port} : $port; return $self->{port}; }