Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active October 19, 2018 19:27
Show Gist options
  • Save Xliff/5ed649b319a4f28b9d77c41516ad8d7d to your computer and use it in GitHub Desktop.
Save Xliff/5ed649b319a4f28b9d77c41516ad8d7d to your computer and use it in GitHub Desktop.
On Overriding method bless()

SOLVED -- See full gist.

Currently at the following version of Perl6

This is Rakudo version 2018.08-48-g741ae6f4e built on MoarVM version 2018.08-28-g2fb3265a1
implementing Perl 6.c.

Application works fine with no errors.

After rakudobrew and am at the following version of Perl6

This is Rakudo version 2018.09-68-g5c272ee41 built on MoarVM version 2018.09-116-g80397b20f
implementing Perl 6.c.

And the previously working code now returns the following error:

Too few positionals passed; expected 1 argument but got 0
  in method bless at /home/cbwood/Projects/p6-GtkPlus/lib/GTK/Window.pm6 (GTK::Window) line 18
  in block  at /home/cbwood/Projects/p6-GtkPlus/lib/GTK/Application.pm6 (GTK::Application) line 89
  in block  at /home/cbwood/Projects/p6-GtkPlus/lib/GTK/Roles/Signals.pm6 (GTK::Roles::Signals) line 27
  in method CALL-ME at /home/cbwood/Projects/rakudobrew/moar-master/install/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 581
  in method run at /home/cbwood/Projects/p6-GtkPlus/lib/GTK/Application.pm6 (GTK::Application) line 200
  in block <unit> at t/14_stack.t line 69

It looks like the code in question is here:

https://github.com/Xliff/p6-GtkPlus/blob/master/lib/GTK/Application.pm6#L203

The issue looks to be that overriding method bless is no longer allowed (or a bug is preventing it). I overrode bless to do the following:

  method bless(*%attrinit) {
    use nqp;
    my $o = nqp::create(self).BUILDALL(Empty, %attrinit);
    $o.setType('GTK::Window');
    $o;
  }

In an object with several "multi method new()" declarations, as well as other new-variants, this saves a lot of time. Without this ability, this code:

  multi method new (
    GtkWindowType $type,
    Str :$title = 'Window',
    Int :$width  = 200,
    Int :$height = 200
  ) {
    my $window = gtk_window_new($type);
    gtk_window_set_title($window, $title);
    gtk_window_set_default_size($window, $width, $height);
    samewith(:$window);
  }
  multi method new (GtkWidget $widget) {
    self.bless(:window($widget));
  }
  multi method new (GtkWindow $window) {
    self.bless(:$window);
  }

Now becomes this code:

  multi method new (
    GtkWindowType $type,
    Str :$title = 'Window',
    Int :$width  = 200,
    Int :$height = 200
  ) {
    my $window = gtk_window_new($type);
    gtk_window_set_title($window, $title);
    gtk_window_set_default_size($window, $width, $height);
    my $o = samewith(:$window);
    $o.setType('GTK::Window');
    $o;
  }
  multi method new (GtkWidget $widget) {
    my $o = self.bless(:window($widget));
    $o.setType('GTK::Window');
    $o;
  }
  multi method new (GtkWindow $window) {
    my $o = self.bless(:$window);
    $o.setType('GTK::Window');
    $o;
  }

As it turns out, it was a bug in rakudo. This was quickly fixed. No changes... well, aside from the fact that you can now override bless. It looks like the proper way to do it without nqp is like this:

  method bless(*%attrinit) {
    my $o = self.CREATE.BUILDALL(Empty, %attrinit);
    ...
    $o;
  }

Thanks to: lizmat, AlexDaniel, and mazak for the healthy discussion and the solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment