6

Can I forward declare a class that I want to load and use later without interpolating its name? I'm trying something like this:

my class Digest::MD5 {};
require ::('Digest::MD5');
put Digest::MD.new.md5_hex("My awesome data to hash");

I know I can do it with interpolation but I was hoping to skip that step:

require ::('Digest::MD5');
put ::('Digest::MD5').new.md5_hex("My awesome data to hash");

I thought I'd seen something like this in some core classes but maybe they had extra stuff going on.

brian d foy
  • 129,424
  • 31
  • 207
  • 592

1 Answers1

9

Splitting up the question:

  1. Can I forward declare a class?

    Yes but the implementation has to be in the same source file.
    (The Rakudo source files are joined into the same file before compilation)
    After all, it has to know which class with that same short-name you are declaring.

    class Foo {...}
    class Foo {
    }
    
  2. Can a class be lazily loaded without having to use ::('Digest::MD5') to access it?

    Yes the return value from require is the class

    put (require Digest::MD5).new.md5_hex("My awesome data to hash");
    

    or you can use this:

    sub term:<Digest::MD5> () { once require Digest::MD5 }
    
    put Digest::MD5.new.md5_hex("My awesome data to hash");
    
Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • Ah, those parens around the `require` are very important. I had tried `my $class = require Digest::MD5` but that is an error. – brian d foy Feb 26 '18 at 10:12