Raku Objects: Confusing or What?

Chapter 1: The Convenience Seeker

Coming from Python, the Raku object model is recognizable, but brings a tad more structure:

Screenshot 2020-05-07 22.36.37

What works for me, as a convenience seeker, is:

  • the attributes $.x, $.y are automatically provided with setter and getter methods
  • the constructor new() is automatically provided
  • the output method e.g. ‘say $p.Str’ is automatically provided
  • I can simply assign to an attribute with ‘=’

These are the things you want if you are writing in a more procedural or functional style and using class as a means to define a record type.

Chapter 2: The Control Freak

Here’s the rub…

When we describe OO, terms like “encapsulation” and “data hiding” often come up. The key idea here is that the state model inside the object – that is, the way it chooses to represent the data it needs in order to implement its behaviours (the methods) – is free to evolve, for example to handle new requirements. The more complex the object, the more liberating this becomes.

However, getters and setters are methods that have an implicit connection with the state. While we might claim we’re achieving data hiding because we’re calling a method, not accessing state directly, my experience is that we quickly end up at a place where outside code is making sequences of setter calls to achieve an operation – which is a form of the feature envy anti-pattern. And if we’re doing that, it’s pretty certain we’ll end up with logic outside of the object that does a mix of getter and setter operations to achieve an operation. Really, these operations should have been exposed as methods with a names that describes what is being achieved. This becomes even more important if we’re in a concurrent setting; a well-designed object is often fairly easy to protect at the method boundary.

(source jnthn https://stackoverflow.com/questions/59671027/mixing-private-and-public-attributes-and-accessors-in-raku)

Let’s fix that:

Screenshot 2020-05-07 22.38.41
Now, I had to do a bit more lifting, but here’s what I got:

  • the private attributes $!x, $!y are formally encapsulated
  • the BUILD submethod does constructor .new() – zero boilerplate needed
  • it takes a method call [$p.y( 2 )] or the colon variant [$p.y: 3] to affect state

And, in contrast to Chapter 1:

  • I cannot assign to has attributes using ‘=’
  • since accessors are explicit I can easily code for constraints and side-effects
  • it’s a pita to code accessors encouraging proper separation of behaviours

Chapter 3: Who Got the Colon in the End?

I also discovered Larry’s First Law of Language Redesign: Everyone wants the colon

Apocalypse 1: The Ugly, the Bad, and the Good https://www.perl.com/pub/2001/04/02/wall.html/

I conclude that Larry’s decision was to confer the colon on the method syntax,  subtly tilting the balance towards the strict model: by preferring $p.y: 3 over $p.y = 2.

3 thoughts on “Raku Objects: Confusing or What?”

  1. From 2020.02, you can use the `is built` attribute on private attributes: `has $!x is built`. That means it *will* allow it to be set from `.new` as a named parameter, but that it will *not* create an accessor for it. This allows you to get rid of the `BUILD` method.

    Liked by 2 people

    1. that’s great news – I get the feeling that raku is designed to let you code in the most effective way for your problem, thus getting out of the way AND to gently nudge you to better habits (encapsulation and so on) by making that the path of least resistance

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s