5

When I run this code

require Readline;
my $rl = Readline.new;
my $string = $rl.readline( ':');
$string.say;

I get this error-message:

You cannot create an instance of this type (Readline)

When I use useto load Readline it works. Why does require Readline not work?

sid_com
  • 24,137
  • 26
  • 96
  • 187
  • Besides the Q+A linked in my dupe vote, you may also find [my answer to **Behaviour of `require` (static + dynamic)**](https://stackoverflow.com/a/62133678/1077672) useful. – raiph May 10 '21 at 16:03

1 Answers1

7

Since require causes the module to be loaded at runtime, the lookup of the Readline symbol must also be deferred until runtime. This can be done using the ::('Type::Name') syntax, as follows:

require Readline;
my $rl = ::('Readline').new;
my $string = $rl.readline( ':');
$string.say;
Jonathan Worthington
  • 29,104
  • 2
  • 97
  • 136
  • One can revert to the usual syntax, and avoid repeating the runtime lookup code, by indirecting via a term, like so: `require Readline; sub term: { ::('Readline') }; my $rl = Readline.new;`. – raiph May 10 '21 at 23:13
  • 2
    No, it feels like a hack; would be better to keep track of it as being a name that wants a late-bound lookup to be produced by the compiler. What if it's a multi-part name? – Jonathan Worthington May 11 '21 at 11:17
  • D'oh. :) Thanks. For later readers: I'd tested creating a multi-part term -- `sub term:` -- and that worked to refer to a `bar` in the `foo` package. But I hadn't tested using a single-part term -- `sub term:` -- and then trying `foo::bar` to refer to the same `bar` in the `foo` package, and that instead yields a run-time error. I've deleted my comment asking jnthn if he thought it made sense to have the compiler do the term trick. I've left my original comment, and my upvote of his, as a tip then warning for later readers. – raiph May 11 '21 at 16:08