Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Thoughts on new 'class' OO in upcoming perl

by tobyink (Canon)
on Mar 06, 2023 at 14:31 UTC ( [id://11150786]=note: print w/replies, xml ) Need Help??


in reply to Thoughts on new 'class' OO in upcoming perl

A lot of your issues can be resolved by using the :common attribute. For example:

class Foo { field $x :param = 0; field $y :param = 0; method create :common ( %args ) { if ( $args{x} < 0 ) { return undef; } else { return $class->new( %args ); } } } my $foo = Foo->create( x => $x, y => $y ) or do_some_error_handling();

Note that this is supported in Object::Pad but not in the first round of implementation for the class keyword (likely to be included in Perl 5.38). As Object::Pad is the testing ground for the class keyword, we can hopefully take it as an indication that :common will be supported in a forthcoming version of Perl, hopefully Perl 5.40.

Replies are listed 'Best First'.
Re^2: Thoughts on new 'class' OO in upcoming perl
by tobyink (Canon) on Mar 06, 2023 at 14:37 UTC

    For what it's worth, I believe this will work, even without support for :common:

    class Foo { field $x :param = 0; field $y :param = 0; } sub Foo::create ( $class, %args ) { if ( $args{x} < 0 ) { return undef; } else { return $class->new( %args ); } } my $foo = Foo->create( x => $x, y => $y ) or do_some_error_handling();

    Not the nicest workaround, but also not terrible.

        How would you prevent someone from calling new() directly, in this case skipping your argument checks?

        Actually, this is possible. Your valid constructor methods just create a sufficiently secure random token and pass this to new. Here's a simple example where you can create objects with calls to the valid_constructor function, but not by directly calling new:

        use 5.37.9; use feature 'class'; no warnings 'experimental'; class No::New { use Carp; field $token :param; my %valid_tokens; ADJUST { delete $valid_tokens{$token} or croak "Directly calling ", __PACKAGE__, "->new is forbidden"; } sub valid_constructor { my $token = rand; $valid_tokens{$token} = 1; __PACKAGE__->new(token => $token); } method text { "Congratulations!"; } } say No::New->valid_constructor->text;

        Such a technique, as already mentioned by tobyink, is entirely impossible for bless. Since all "traditional" Perl OO frameworks including Object::Pad are based on blessed references, only core OO can prevent objects like bless \q"Arbitrary junk", Your::Class from happening!

Re^2: Thoughts on new 'class' OO in upcoming perl
by haj (Vicar) on Mar 06, 2023 at 20:16 UTC

    Note that you can have "traditional" subroutines declared as sub create ($class,%args) in a class. The method keyword just simplifies the signature declaration because the class (for common methods) or instance(for object methods) are implied and provided as lexicals.

Re^2: Thoughts on new 'class' OO in upcoming perl
by Jenda (Abbot) on Mar 17, 2023 at 20:52 UTC
    :common
    Since version 0.62.

    Marks that this method is a class-common method, instead of a regular instance method. A class-common method may be invoked on class names instead of instances. Within the method body there is a lexical $class available, rather than $self. Because it is not associated with a particular object instance, a class-common method cannot see instance fields.

    Ah. You mean static. OK.

    I mean ... these things are called either static methods or class methods. ":common" ... what are they even common for? Is there actually any language in which these would be called common methods?

    Jenda
    1984 was supposed to be a warning,
    not a manual!

      Is there actually any language in which these would be called common methods?

      I agree with your point. It's just Perl being gratuitously different, yet again — like the ridiculous "invocant" vice the standard term "object" (or else "receiver"). Being gratuitously different is the main thing I hate so much about Python. Perl should be better than that. Really, stuff like this is what makes Perl look stupid. It makes it look like our best and brightest don't even know the standard terms of art. ("Invocant" is especially bad because it makes it clear that our people don't know the most basic Latin either.)

      Today's latest and greatest software contains tomorrow's zero day exploits.

        Calling the invocant an object would be misleading though, as it's often just a string class name.

        "Invocant" is being used as an English word, without necessarily the same meaning as in Latin. Consider how wildly the meaning of words like "genius" have been altered when borrowed into English. Altering the meaning is fine. I don't think many people are being confused by how the term differs from what they learnt in their Latin classes. The whole medical community is out there using words like "tonsillitis" (Latin word with a Greek suffix) and "dehydration" (Greek word with a Latin prefix and a Latin-derived suffix) and I don't think that the world perceives doctors as stupid as a result.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11150786]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2025-06-13 20:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.