Search code examples
raku

How do I create a class with the same name as a built-in one without overshadowing it in Raku?


This is quite silly and I know the obvious thing to do is simply naming the class differently but I'm still curious. In the class ColumnType::Date, I'd like typecast to return a Raku's Date object, and not a ColumnType::Date one:

module ColumnType {
    class Date {
        method typecast(Blob:D $value) {
            my $date = $value.decode('ascii').trim;
            my ($year, $month, $day) = $date.split('/');
            return try Date.new: :$year, :$month, :$day;
        }
    }
}

my $blob = "1980/01/01".encode('ascii');
say ColumnType::Date.new.typecast($blob);

In other words, is it possible to reference Raku's Date as a fully-qualified name?


Solution

  • Yes. By prefixing CORE::.

    $ raku -e 'say CORE::Date =:= Date'
    True
    

    EDIT:

    More generally, you can access something that is lexically available after lexically overriding it, by using my constant. In your example, you could also have done:

    module ColumnType {
        my constant OriginalDate = Date;
        class Date {
            method typecast(Blob:D $value) {
                my $date = $value.decode('ascii').trim;
                my ($year, $month, $day) = $date.split('/');
                return try OriginalDate.new: :$year, :$month, :$day;
            }
        }
    }
    

    This will "save" the visibility of the class Date inside the module as OriginalDate, which you can then use to call .new on.