如何重新加载REPL中使用的模块?

时间:2018-09-28 16:17:21

标签: perl6

这个问题很容易解释。如果在开发过程中将模块加载到REPL中,则无需先exit就可以进行更改。

2 个答案:

答案 0 :(得分:4)

您可以使用EVALFILE
(有一些警告)

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

当您尝试使用名称空间时就会出现问题。

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

如果在每次加载之间更改名称的:ver部分,此操作仍然无效。

lib / example.pm6

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

要解决这个问题,一种解决方法是使它们词汇化而不是全局化。

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

尽管如此,它具有单独的词汇范围:

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

所以您将要为其别名:

> 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

这当然是有效的,因为类定义是该作用域中的最后一条语句。


如果您深入研究Rakudo的结构,也许有一种方法可以像在Perl 5中那样引起重新加载,但是据我所知,这不是该语言的一部分。

答案 1 :(得分:-2)

就像Python的导入一样,您可以使用use关键字:

> 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

有关更多信息,https://docs.perl6.org/language/modules#Exporting_and_selective_importing可能会有所帮助。