GitHub | 1 Feb 2012 06:27

[perl6/specs] 588f3e: move smartmatch toward treating Match like Bool

  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 588f3ef1964d440d1e1cfc20dd17e84a9600f521
      https://github.com/perl6/specs/commit/588f3ef1964d440d1e1cfc20dd17e84a9600f521
  Author: Larry Wall <larry <at> wall.org>
  Date:   2012-01-31 (Tue, 31 Jan 2012)

  Changed paths:
    M S03-operators.pod

  Log Message:
  -----------
  move smartmatch toward treating Match like Bool

  Commit: e73bd99f9826170835a55753c1b0bbbfb6bdc120
      https://github.com/perl6/specs/commit/e73bd99f9826170835a55753c1b0bbbfb6bdc120
  Author: Larry Wall <larry <at> wall.org>
  Date:   2012-01-31 (Tue, 31 Jan 2012)

  Changed paths:
    M S12-objects.pod

  Log Message:
  -----------
  Merge branch 'master' of github.com:perl6/specs

Compare: https://github.com/perl6/specs/compare/f4488b0...e73bd99
GitHub | 1 Feb 2012 06:58

[perl6/specs] c7c7de: ? already implied by 'if' in header, moritz++

  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: c7c7def0941ba1713d1fd09481dcb012259a6102
      https://github.com/perl6/specs/commit/c7c7def0941ba1713d1fd09481dcb012259a6102
  Author: Larry Wall <larry <at> wall.org>
  Date:   2012-01-31 (Tue, 31 Jan 2012)

  Changed paths:
    M S03-operators.pod

  Log Message:
  -----------
  ? already implied by 'if' in header, moritz++

yary | 1 Feb 2012 20:40
Picon
Gravatar

Setting private attributes during object build

I wrote my first perl6 over the weekend, needing some help on #perl6.
And now after finishing some lunchtime thoughts I wanted to post here
on my main sticking point.

If one wants to set a private attribute, one must define a "submethod
BUILD". If one wants to use any argument in the constructor other than
a public attribute (positional OR named other than an attribute name),
one must define a "method new( ... )".

And if one wants to do both, then the initialization code must be
spread between "method new ( ... )" and "submethod BUILD".

One fix posited on #perl6 was a "blessall" method that would act like
"bless", but also allow setting private attributes. That would be a
solution... but... how about going all the way and allowing "bless" to
set private attributes? I wasn't looking when the decisions were made
about bless, and I can understand an argument about not letting
private attributes leak out. On the other hand, if it's OK for a new
"blessall", why not for "bless" itself instead?

-y

Jonathan Lang | 1 Feb 2012 21:24
Picon

Re: Setting private attributes during object build

Why must we use 'submethod BUILD' instead of 'method BUILD'?  Is it some sort of chicken-and-egg dilemma?  

Carl Mäsak | 1 Feb 2012 21:31
Picon
Gravatar

Re: Setting private attributes during object build

Jonathan Lang (>):
> Why must we use 'submethod BUILD' instead of 'method BUILD'?  Is it some
> sort of chicken-and-egg dilemma?

Philosophically, BUILD submethods are submethods because they do
infrastructural stuff that is very tied to the internals of the class.
Submethods are "internal" methods rather than "external" methods (like
accessors, for example). Submethods don't inherit; each BUILD is
specific to the class it finds itself in and not its deriving classes.
The only sense in which it's akin to a chicken-and-egg dilemma is that
a BUILD submethod assumes that it can access the class's attributes,
but not that it can use accessors and other external methods.

// Carl

yary | 1 Feb 2012 21:33
Picon
Gravatar

Re: Setting private attributes during object build

On Wed, Feb 1, 2012 at 3:24 PM, Jonathan Lang <dataweaver <at> gmail.com> wrote:
> Why must we use 'submethod BUILD' instead of 'method BUILD'?
> Is it some sort of chicken-and-egg dilemma?

from S12:
"Submethods are for declaring infrastructural methods that shouldn't
be inherited by subclasses, such as initializers ... only the methods
are visible to derived classes via inheritance. A submethod is called
only when a method call is dispatched directly to the current class."

It isn't chicken-and-egg, it's safety. The BUILD submethod doesn't get
used for anything other than the class it is defined in, even if that
class is derived from.

-y

Carl Mäsak | 1 Feb 2012 23:41
Picon
Gravatar

Re: Setting private attributes during object build

Jonathan Lang (>>), yary (>):
>> Why must we use 'submethod BUILD' instead of 'method BUILD'?
>> Is it some sort of chicken-and-egg dilemma?
>
> from S12:
> "Submethods are for declaring infrastructural methods that shouldn't
> be inherited by subclasses, such as initializers ... only the methods
> are visible to derived classes via inheritance. A submethod is called
> only when a method call is dispatched directly to the current class."
>
> It isn't chicken-and-egg, it's safety. The BUILD submethod doesn't get
> used for anything other than the class it is defined in, even if that
> class is derived from.

When I first used submethods, I thought of them as just
subroutine-method hybrids: they are a little like subs because they
don't inherit. They are a little like methods because they take an
invocant. I didn't much care about the "infrastructural" bit, mostly
using them as a kind of private methods. (Nowadays I use private
methods as private methods.) :-)

Getting back to the topic of the original post: I think "blessall" is
a bad name for what's proposed, and I don't see a fantastically large
need for that functionality. What's wrong with just defining a BUILD
submethod in the class?

I also don't see a problem of having to divide initialization code
between .new and .BUILD. They have different purposes -- .new is
outwards-facing, receiving arguments. .BUILD is infrastructural and
inwards-facing, building up (as the name suggests) your attributes. If
(Continue reading)

yary | 2 Feb 2012 00:36
Picon
Gravatar

Re: Setting private attributes during object build

On Wed, Feb 1, 2012 at 5:41 PM, Carl Mäsak <cmasak <at> gmail.com> wrote:
...
>Getting back to the topic of the original post: I think "blessall" is
>a bad name for what's proposed, and I don't see a fantastically large
>need for that functionality. What's wrong with just defining a BUILD
>submethod in the class?

Limiting settable attributes inside "new" feels arbitrary. It
frustrated me as a beginner. I don't have an opinion on "blessall" as
a concept or as a name; I do like it as a solution to having to put
object init code in different blocks.

> I also don't see a problem of having to divide initialization code
> between .new and .BUILD. They have different purposes -- .new is
> outwards-facing, receiving arguments. .BUILD is infrastructural and
> inwards-facing, building up (as the name suggests) your attributes. If
> you need to modify both these behaviors, you override both.
>
> // Carl

"new" faces outwards but it cannot help but play inwards when it calls
"bless". (And if a method "new" does not call "bless", then it isn't a
constructor.)

-y

yary | 2 Feb 2012 00:42
Picon
Gravatar

Re: Setting private attributes during object build

Looking back at my paltry code, what I ended up doing was having a
BUILD submethod that just listed all my attributes, private and
public, and an empty block, essentially turning "bless" into
"blessall". Which makes submethod BUILD looks like boilerplate, a
magic invocation, repeated in my classes. Not very elegant looking.
Not horrible, just not as good as it could be IMHO.

Moritz Lenz | 2 Feb 2012 06:01
Gravatar

Re: Setting private attributes during object build

On 02/01/2012 11:41 PM, Carl Mäsak wrote:
> Getting back to the topic of the original post: I think "blessall" is
> a bad name for what's proposed, and I don't see a fantastically large
> need for that functionality. What's wrong with just defining a BUILD
> submethod in the class?

The current approach is violating the DRY principle. When you write a
.new method that wants to initialize private attributes, you have to
repeat all their names again in the signature of your BUILD submethod:

class A {
    has ($!x, $!y, $!z);
    method new($x, $y, $z) { self.bless(*, :$x, :$y, :$z) }
    submethod BUILD(:$!x, :$!y, :$!z) { } # is this repetition really
needed?
}

It also means that private attributes are less convenient to work with
than those with accessors, which IMHO is a not signal in the right
direction.

Cheers,
Moritz


Gmane