Skip to content

Instantly share code, notes, and snippets.

@skids
Created May 22, 2012 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skids/2771728 to your computer and use it in GitHub Desktop.
Save skids/2771728 to your computer and use it in GitHub Desktop.
Current working rakudo recipe for making a CStruct member behave like a given type.
# Current working rakudo recipe for making a CStruct member behave like a
# given type. (As of rakudo/rakudo 22c12b0cffa05d999fbf84b83eeb551922860ed5)
class A is repr('CStruct') {
# For a rw attribute, must use a private attribute. Using $.x gives error:
# "Cannot create rw-accessors for natively typed attribute '$!x'"
# (Also if you use $.x and then try to make a method x to write your
# own accessors you get an infinite loop at runtime.
# BUT, if you use $.x, leave a bogus method x which you never call,
# and then write a rw accessor using a different name, things work,
# but we don't need to do that.)
has int32 $.x is rw; # Cannot do = 36500;
# Error message if you try to use a default value above:
# "CStruct representation attribute not yet fully implemented"
submethod BUILD { $!x = 36500 };
# Why we need these is explained below
method !get_x { $!x; }
method !set_x ($v) { $!x = $v; }
# Now we roll our own rw accessor.
multi method x is rw {
# If you attempt to use $!x in the Proxy methods below, you get
# error: "Can not get non-existent attribute '$!x' on class 'A'"
# If you attempt to use "self" in the Proxy methods below, you
# get an infinite loop at runtime.
# But it seems that a bind to self does work.
my $f := self;
# If you try to use $f!x in the below methods, you get the
# error: "Private method 'x' not found on type A"
# (and that is the reason for the above get_x, set_x methods)
Proxy.new(FETCH => method { Date.new-from-daycount($f!get_x) },
STORE => method ($v) { $f!set_x(Date.new($v).daycount) }
);
}
}
my A $a .= new();
$a.x.say;
$a.x = "2012-10-10";
$a.x.say;
# Yes, you can bind to attributes even when using Proxy. Yay!
my $b;
$b := $a.x;
$b.say;
$b = "2012-11-11";
$b.say;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment