6

The question is pretty self explanatory. If I load a module in the REPL during development I would like to pick up changes without having to exit first.

matthias krull
  • 4,389
  • 3
  • 34
  • 54
  • You are asking the REPL to perform IDE-like functions. Perhaps you should look at using [Comma](https://commaide.com). Because that's an IDE made specifically for Perl 6, and has the feature you are asking for here. And then some :-) – Elizabeth Mattijsen Sep 30 '18 at 19:37
  • No I don't ask for IDE functionality, really. I am looking for something like Ruby's `load` or Pythons `execfile` maybe? – matthias krull Oct 01 '18 at 09:03

2 Answers2

6

You can use EVALFILE
(With some caveats)

lib/example.pm6

say (^256).pick.fmt('%02X')

REPL

> EVALFILE('lib/example.pm6'); # rather than `use lib 'lib'; use example;`
DE
> EVALFILE('lib/example.pm6');
6F

The problem comes when you try to use a namespace.

lib/example.pm6

class Foo {
  say (^256).pick.fmt('%02X')
}

REPL

> EVALFILE('lib/example.pm6')
C0
> EVALFILE('lib/example.pm6')
===SORRY!=== Error while compiling /home/brad/EVAL_2
Redeclaration of symbol 'Foo'
at /home/brad/EVAL_2:1
------> class Foo⏏ {
    expecting any of:
        generic role

This still doesn't work if you change the :ver part of the name between each time you load it.

lib/example.pm6

class Foo:ver(0.001) {
  say (^256).pick.fmt('%02X')
}

One way to get around this if you are just experimenting is to make them lexical rather than global.

lib/example.pm6

my class Foo {  # default is `our`
  say (^256).pick.fmt('%02X')
}

REPL

> EVALFILE('lib/test.pm6')
DD
> EVALFILE('lib/test.pm6')
88
> EVALFILE('lib/test.pm6')
6E

It has a separate lexical scope though:

> Foo
===SORRY!=== Error while compiling:
Undeclared name:
    Foo used at line 1

So you will want to alias it:

> my \Foo = EVALFILE('lib/test.pm6'); # store a ref to it in THIS lexical scope
0C
> Foo
(Foo)

> my \Foo = EVALFILE('lib/test.pm6'); # still works the second time
F7

This of course only works because the class definition is the last statement in that scope.


There may be a way to cause a reload similar to how you can in Perl 5 if you dig into the structure of Rakudo, but as far as I know this is not available as part of the language.

Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
  • How to use variables defined in `lib/example.pm6` ? – Tinmarino Feb 21 '20 at 17:56
  • 1
    @tinmarino You could probably have the last value in the file be a list like: `($foo,$bar,Foo)`, and then deconstruct it when you use it like: `my ($foo,$bar,\Foo) = EVALFILE('lib/test.pm6')` – Brad Gilbert Feb 26 '20 at 17:02
-2

Like Python's import, you can use the use keyword:

> perl6
To exit type 'exit' or '^D'
> use Cro::HTTP::Client
Nil
> my $resp = await Cro::HTTP::Client.get('https://www.perl6.org/');
Cro::HTTP::Response.new(request => Cro::HTTP::Request, status => 200, body-parser-selector => Cro::HTTP::BodyParserSelector::ResponseDefault, body-serializer-selector => Cro::HTTP::BodySerializerSelector::ResponseDefault, http-version => "1.1", http2-stream-id => Int)
> say await $resp.body

For more information, https://docs.perl6.org/language/modules#Exporting_and_selective_importing may be help.

chenyf
  • 5,048
  • 1
  • 12
  • 35
  • 1
    I think the OP is asking how to **re**load a module after changes to the module without having to exit and reload the REPL. – raiph Sep 29 '18 at 03:57
  • @raiph Probably. I also wander how to reload module in REPL without exit first. Python's REPL should do this, as far as i know. – chenyf Sep 29 '18 at 04:48