在 Perl 脚本运行时安装 Term::ReadLine::Gnu 并使用脚本中的模块
我正在编写一个程序供其他人使用。设计规范之一是使用 Term::ReadLine::Gnu Perl 库。大多数用户不会安装它,而我想在程序运行时安装它。
因此,当用户启动程序时,他们没有安装该库。我的程序将在他们使用操作系统包管理器使用该程序时为他们安装它。
这就是我检查模块的方式
require Term::ReadLine;
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
,我使用 $Readline_Support 变量来重定向终端,使用历史文件等。
$OUT = $TERMINAL->OUT if $readline_installed;
if ($readline_installed)
{
# save every answer and default, good or not, to the history file
$TERMINAL->add_history($Ans);
$TERMINAL->append_history(1, HIST_FILE);
}
不幸的是,当我尝试使用历史文件时,我收到此错误:
无法定位对象方法“using_history” " via package "Term::ReadLine::Stub" at ./msi.pl 第 618 行,第 2 行。
第 618 行是
$TERMINAL->using_history();
$TERMINAL 对象的第一次使用。
有没有人有过在脚本运行时安装 Perl 模块,然后在同一脚本中使用这些模块的经验?
好的...感谢 Andy,如果未安装模块,则可以
# I removed the require Term::ReadLine; here
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
在代码中进行下面的
if ($readline_installed)
{
# Required for the dynamic loading of Term::ReadLine::Gnu
require Term::ReadLine;
$TERMINAL = Term::ReadLine->new ('ProgramName')
if $Interactive or $Brief
}
操作,但是现在,对已安装 mod 的检查总是失败,我认为因为
require Term::ReadLine::Gnu;
需要
require Term::ReadLine;
在代码的早期进行,就像旧的一样
require Term::ReadLine;
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
I'm writing a program for others to use. One of the design specs is to use the Term::ReadLine::Gnu Perl library. Most of the users will not have this installed and I want to install it while the program is running.
So, when the user starts the program they do not have the library installed. My program will install it for them while they are using the program using the OS package manager.
This is how I'm checking for the module
require Term::ReadLine;
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
I use the $Readline_Support variable to redirect the terminal, use the history file etc.
$OUT = $TERMINAL->OUT if $readline_installed;
if ($readline_installed)
{
# save every answer and default, good or not, to the history file
$TERMINAL->add_history($Ans);
$TERMINAL->append_history(1, HIST_FILE);
}
Unfortunately, I get this error when I try to use the history file:
Can't locate object method "using_history" via package "Term::ReadLine::Stub" at ./msi.pl line 618, line 2.
line 618 is
$TERMINAL->using_history();
Which is the first use of the $TERMINAL object.
Has any one had experience with installing Perl modules while the script is running and then using the modules in that same script?
Ok... Thanks to Andy if the module is not installed this works
# I removed the require Term::ReadLine; here
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
below in the code
if ($readline_installed)
{
# Required for the dynamic loading of Term::ReadLine::Gnu
require Term::ReadLine;
$TERMINAL = Term::ReadLine->new ('ProgramName')
if $Interactive or $Brief
}
Now, however, the check for the installed mod always fails, I think because
require Term::ReadLine::Gnu;
needs
require Term::ReadLine;
early in the code, like the old
require Term::ReadLine;
my $Readline_Support = 1;
eval { require Term::ReadLine::Gnu }
or $Readline_Support = 0;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你在这里逆流而行。没有其他人这样做,并且在安装后更改系统也会让我认识的大多数系统管理员感到不安。
只需声明依赖关系,这样当您的程序安装时,T::R::G 也会被安装。我链接到 How 中的相关文档我要为遗留系统创建构建吗?。
该工具链已经为您提供了所有必要的部分,使每个参与其中的人都可以轻松完成此任务,请务必了解它。
You're swimming against the flow here. No one else does it this way, and changing a system after installation would also upset most system admins I know.
Simply declare the dependency, so when your program is installed, T::R::G is also installed. I link to the pertinent documentation in How do I create a build for a legacy system?.
The toolchain gives you already all the necessary bits to make this painless for everyone who is involved, do learn about it.
您可以从“cpan”命令本身学习。 cpan 可以自行安装(升级)并随后重新加载所有使用的模块。这应该是一个很好的学习起点。
You can learn from the "cpan" command itself. cpan can install (upgrade) himself and reload all used modules afterward. That should be a good starting point for learning.
我在
Term::ReadLine
的代码中看到,它决定在加载时使用哪个实现,而不是在调用new
时使用。因此,我建议按照以下顺序:Term::ReadLine::Gnu
的可用性,就像您当前一样,但在加载任何ReadLine
模块之前Term ::ReadLine::Gnu
如果不存在require Term::ReadLine
Term::ReadLine->new
创建对象事情变得更加复杂,因为
Term::ReadLine::Gnu
在尝试使用use
或require
直接加载它时会抛出错误,因此直接的eval即使安装了,测试也会失败。解决这个问题的一种方法是解析
$@
,但我不喜欢解析诊断消息,因为它们可能会随着时间的推移而改变。从%INC
中删除似乎也不是很好,但只要直接加载Term::ReadLine::Gnu
上的错误不消失就应该可以工作。I see in the code for
Term::ReadLine
that it determines which implementation it is going to use at load time, as opposed to whennew
is called. So I would suggest the following sequence:Term::ReadLine::Gnu
just like you are currently, but before loading anyReadLine
modulesTerm::ReadLine::Gnu
if not presentrequire Term::ReadLine
Term::ReadLine->new
Things are made more complicated because
Term::ReadLine::Gnu
throws an error on an attempt to load it directly withuse
orrequire
, so the straightforwardeval
test fails even when it's installed. One way to deal with that is to parse$@
, but I don't like parsing diagnostic messages because there's a risk they may change over time. Deleting from%INC
doesn't seem great either, but should work as long as the error on a direct load ofTerm::ReadLine::Gnu
doesn't go away.