Created
May 22, 2012 21:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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