- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我基本上是模块的新手,我正在尝试在我的脚本中使用它们。我无法找到正确使用它们的正确方法,我希望得到你的建议。
让我快速解释一下我要做什么:
我的脚本正在根据 XML 文件中的数据进行一些文件传输。
所以基本上,我有包含类似内容的 XML 文件:
<fftg>
<actions>
<!-- Rename file(s) -->
<rename>
<mandatory>0</mandatory>
<file name="foo" to="bar" />
</rename>
<!-- Transfer file(s) -->
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<server>fqdn</server>
<port>22</port>
<file name="bar" remotefolder="toto" />
</transfer>
<!-- Transfer file(s) -->
<transfer>
<mandatory>0</mandatory>
<protocol>SFTP</protocol>
<server>fqdn</server>
<port>22</port>
<file name="blabla" remotefolder="xxxx" />
<file name="blabla2" remotefolder="xxxx" />
</transfer>
</actions>
</fftg>
简而言之,我有一个执行“ Action ”的脚本。每个 Action 都可以重复 X 次。
现在,我认为最好为我的应用程序创建模块,并将操作放在模块中,而不是让一个重要的脚本包含一堆子程序等。
例如:
FFTG::Rename
FFTG::Transfer
FFTG::Transfer::SFTP
FFTG::Transfer::FTP
& 等等(我已经创建了所有这些模块并且它们可以独立工作)
并根据 XML 文件中指定的操作调用这些模块。如果需要,人们可以创建新的模块/操作(我希望它是模块化的)。
现在,我不知道如何正确地做到这一点。
所以我的问题是:最好的方法是什么?
目前,我的脚本正在读取这些 Action :
# Load XML file
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($FFTG_TSF . "/" . $tid . ".xml");
# Browse XML file
foreach my $transfer ($doc->findnodes('/fftg')) {
# Grab generic information
my($env) = $transfer->findnodes('./environment');
my($desc) = $transfer->findnodes('./description');
my($user) = $transfer->findnodes('./user');
print $env->to_literal, "\n";
# Browse Actions
foreach my $action ($doc->findnodes('/fftg/actions/*')) {
my $actiontype = ucfirst($action->nodeName());
# how do i select a module from the $actiontype here ? ($actiontype = Rename or Transfer)
# i can't do : use FFTG::$actiontype::execaction(); or something for example, it doesnt work
# and is it the right way of doing it ?
}
}
但也许这不是正确的思考方式。 (我正在使用 Lib::LibXML)我如何“动态地”调用模块(在名称中使用变量,例如 FFTG::$actiontype而且,这是否意味着我必须在每个模块中都有相同的子程序?示例:子执行
因为我想向模块发送不同的数据......
有什么提示吗?再次感谢问候,
最佳答案
首先,您需要设计一个清晰的界面。每个模块都需要具有相同的结构。是否面向对象无关紧要,但它们都需要公开相同的接口(interface)。
这里是 FFTG::Rename
的非 OOp 实现示例。我遗漏了很多东西,但我认为很清楚发生了什么。
package FFTG::Rename;
use strict;
use warnings;
sub run {
my ($args) = @_;
if ($args->{mandatory}) {
# do stuff here
}
# checks args...
# do sanity checks...
return unless -f $args->{file}->{name}; # or whatever...
rename $args->{file}->{name}, $args->{file}->{to} or die $!;
return; # maybe return someting meaningful?
}
现在让我们假设我们有一堆这样的东西。我们如何加载它们?做这件事有很多种方法。我省略了将参数放入 run
函数的部分。您需要从 XML 中获取内容并以与所有这些功能相同的方式传递它,但我认为这与问题无关。
最明显的是手动将它们全部加载到脚本中。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::LibXML;
# load FFTG modules
use FFTG::Rename;
# ...
加载完成后,您就可以调用函数了。 exist
keyword很方便,因为它也可用于检查函数是否存在。
foreach my $action ( $doc->findnodes('/fftg/actions/*') ) {
my $actiontype = ucfirst( $action->nodeName );
no strict 'refs';
if ( exists &{"FFTG::${actiontype}::run"} ) {
&{"FFTG::${actiontype}::run"}->( $parsed_node_information );
} else {
# this module was not loaded
}
}
不幸的是,非 OO 方法需要 no strict 'refs'
,这并不漂亮。以面向对象的方式进行可能更好。但我会坚持这个答案。
这种方式的明显缺点是您需要始终加载所有模块,并且每当创建新模块时,都需要添加它。这是最不复杂的方式,但也具有最高的维护性。
另一种方法是使用自动加载和定义允许的操作的查找表。如果您希望您的程序仅按需加载模块,因为您知道您不需要在每次调用时都需要所有模块,但您还希望控制加载的内容,这是有道理的。
不是加载所有这些,加载可以外包给Module::Runtime .
use Module::Runtime 'require_module';
use Try::Tiny;
my %modules = (
'rename' => 'FFTG::Rename',
# ...
);
foreach my $action ( $doc->findnodes('/fftg/actions/*') ) {
try {
no strict 'refs';
require_module $modules{$action};
&{"FFTG::${actiontype}::run"}->($parsed_node_information);
}
catch {
# something went wrong
# maybe the module does not exist or it's not listed in the lookup table
warn $_;
};
}
我还添加了 Try::Tiny负责错误处理。它使您可以控制出现问题时的处理方式。
这种方法可以让您控制允许的操作,如果您偏执,这很好。但它仍然需要您维护脚本并将新模块添加到 %modules
查找表中。
第三种最通用的方法是使用 Module::Runtime 动态加载内容,无需查找表。
use Module::Runtime 'require_module';
use Try::Tiny;
foreach my $action ( $doc->findnodes('/fftg/actions/*') ) {
try {
my $actiontype = ucfirst($action->nodeName);
require_module "FFTG::${actiontype}";
no strict 'refs';
&{"FFTG::${actiontype}::run"}->($parsed_node_information);
}
catch {
# something went wrong
# the module does not exist
};
}
这需要最少的维护,但也有点危险。您不知道传入的数据是什么,现在也没有健全性检查。我想不出一种方法来利用我的头脑,但可能有一个。不过,现在不需要编辑脚本并保持模块列表为最新。
我可能会选择第二种方法。它使您可以控制并仍然保持动态。我不会采用我使用过的非 OOP 方法。
您可以通过使用 ->
对象符号来调用类方法,使其保持非 OOP 并仍然摆脱 no strict 'refs'
。那么您的包裹将如下所示。
package FFTG::Rename;
use strict;
use warnings;
sub run {
my (undef, $args) = @_;
# ...
}
undef
是为了不捕获$class
(不是$self
),因为我们不需要它。或者也许我们这样做,用于日志记录。这取决于。但是有了这个,您基本上可以为查找表解决方案调用类方法,如下所示。
require_module $modules{$action};
$modules{$action}->run($parsed_node_information);
这显然更清晰、更可取。
关于xml - 使用 Perl 模块时的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129391/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!