我刚刚在代码审查中被要求检查调用Perl模块GetOptions()函数的返回代码Getopt::Long.
我不记得曾见过这样的GetOptions()功能测试.
那么人们通常不会检查此函数的返回码是否有特定的原因?
可以在Perl 5中system()拨打电话die吗?
(换句话说,为了100%防止system()打电话的程序,它是否需要被包装成一个eval块,还是完全没必要?)
我没有找到这种可能性perldoc system,但没有找到准确的"这个呼叫永远不会死".
注意:问题是关于这里的基本CORE Perl,没有autodie或任何其他具有类似效果的自定义模块.此外,假设没有ALRM设置信号,或任何其他自定义信号处理程序.
我假设Perl 5.*的所有版本都表现相同,但如果没有,则可以理解与5.8相关的答案.
问题:
我有一个带有gajillion(> 100)成员的C++类,它们的行为几乎相同:
相同的类型
在函数中,每个成员具有与其他成员相同的完全代码,例如,从构造函数中的映射赋值,其中map键与成员键相同
在许多函数(> 20)中重复这种行为的相同性,当然每个函数中的行为是不同的,所以没有办法解决问题.
成员列表非常流畅,具有不断添加和有时删除,一些(但不是全部)由更改DB表中的列驱动.
您可以想象,就代码创建和维护而言,这是一个很大的痛苦,因为要添加新成员,您必须为使用类似成员的每个函数添加代码.
我想要的解决方案示例
我需要的实际C++代码(例如,在构造函数中):
MyClass::MyClass(SomeMap & map) { // construct an object from a map
intMember1 = map["intMember1"];
intMember2 = map["intMember2"];
... // Up to
intMemberN = map["intMemberN"];
}
Run Code Online (Sandbox Code Playgroud)
我希望能够编写的C++代码:
MyClass::MyClass(SomeMap & map) { // construct an object from a map
#FOR_EACH_WORD Label ("intMember1", "intMember2", ... "intMemberN")
$Label = map["$Label"];
#END_FOR_EACH_WORD
}
Run Code Online (Sandbox Code Playgroud)
要求
该解决方案必须与GCC兼容(如果重要的话,使用Nmake作为make系统).不关心其他编译器.
解决方案可以是预处理器级别,也可以是可编译的.我对任何一个都很好; 但是到目前为止,我的所有研究都指出了这样的结论:后者在C++中显然是不可能的(我现在很想念Perl,因为我被迫做C++!)
解决方案必须至少在某种程度上是"行业标准"(例如Boost很棒,但Joe-Quick-Fingers创建一次并在他的博客上发布的自定义Perl脚本不是.哎呀,我可以很容易地写出Perl脚本,更像是Perl专家而不是C++专家 - 我只是无法让我的BigCompany的软件工程大佬们购买使用它:))
解决方案应该允许我声明一个ID列表(理想情况下,只在一个头文件中而不是在每个"#FOR_EACH_WORD"指令中,就像我在上面的示例中所做的那样)
解决方案不能仅限于"从DB表创建对象"构造函数.有许多功能,其中大多数不是构造函数,需要它.
解决方案"在一个向量中创建所有值,然后在向量上运行'for循环"是一个明显的解决方案,并且无法使用 - 许多应用程序使用的库中的代码,成员是公共的遗憾的是,重写这些应用程序以使用向量成员而不是命名成员是不可能的.
在Perl中,当你有一个嵌套的数据结构时,允许省略取消引用箭头到2d和更多嵌套级别.换句话说,以下两个语法是相同的:
my $hash_ref = { 1 => [ 11, 12, 13 ], 3 => [31, 32] };
my $elem1 = $hash_ref->{1}->[1];
my $elem2 = $hash_ref->{1}[1]; # exactly the same as above
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是,是否有充分的理由选择一种风格而不是另一种风格?
它似乎是风格争论的流行之骨(Just on SO,我不小心碰到了这个,这在5分钟的时间内).
到目前为止,几乎所有通常的嫌疑人都没有明确表示:
"掌握Perl for Bioinfirmatics"作者James Tisdall也没有给出非常可靠的偏好:
"明智的读者可能已经注意到我们似乎在数组下标之间省略了箭头操作符.(毕竟,这些是匿名数组的匿名数组的匿名数组等,所以不应该写它们[$ array- > [$ i] - > [$ j] - > [$ k]?)Perl允许这样做;只需要变量名和第一个数组下标之间的箭头操作符.它使眼睛更容易,有助于避免腕骨隧道综合症.另一方面,您可能更愿意保留解除引用箭头,以明确您正在处理引用.您的选择."
更新的 "中级Perl",根据其共同作者brian d foy,建议省略箭头.请参阅下面的brian的完整答案.
就个人而言,我站在"总是放箭头,因为它更具可读性和显而易见性,他们正在处理参考".
更新更具体的re:可读性,在多嵌套表达式的情况下,下标本身是表达式,箭头通过更明显地将下标彼此分开来帮助"在视觉上标记化"表达式.
我想知道Perl的最佳实践是关于获取 - 或者更重要的是设置 - 某个模块的全局变量,通过直接访问$Module::varName以防模块没有为它提供getter/setter方法.
它闻起来不好的原因是它有点绕过封装.仅仅因为我可以在Perl中完成它,我不完全确定我应该(假设实际上有一个替代方法,比如在模块中添加一个getter/setter).
我在Perl中使用了一些系统命令.
在下面的例子中,我获得如下输出:
ls: import-log.*: No such file or directory
ls: error-log.*: No such file or directory
No specified files found for deletion
Run Code Online (Sandbox Code Playgroud)
我的代码:
sub monthoryear()
{
@importlog = `ls -al import-log.*`;
@errorlog = `ls -al error-log.*`;
}
Run Code Online (Sandbox Code Playgroud)
即使没有文件,我也不希望在输出中看到以下内容.
ls: import-log.*: No such file or directory &
ls: error-log.*: No such file or directory
Run Code Online (Sandbox Code Playgroud) 技术问题:
鉴于正则表达式:
my $regEx = qr{whatever$myVar}oxi; # Notice /o for "compile-once"
Run Code Online (Sandbox Code Playgroud)
什么是迫使它按需重新编译的最有效方法?(例如,当我从程序逻辑中知道$myVar值已经改变时)没有掉线/o并依赖于Perl的内部智能来自动重新编译?
注意:正则表达式用于替换,这可能会影响重新编译规则sans/o:
$string2 =~ s/$regEx//;
Run Code Online (Sandbox Code Playgroud)
背景是:
我有一个正则表达式,它是通过从配置文件中插入一个相当长(> 1k长)的字符串构建的.
该文件每60分钟重新读取一次.
如果从文件读取的字符串发生更改(通过更改文件时间戳定义),我想使用重新标记的字符串值重新编译正则表达式$myVar.
在mod_perl下运行的Perl模块中重复使用正则表达式.
这意味着(加上字符串长度> 1-2k)我必须使用" /o"修饰符强制在正则表达式上编译一次,以避免Perl的性能损失反复检查变量值是否发生变化(此启发式来自perlop qr//,自正则表达式用作s///上面所示的一部分,而不是作为匹配本身.
这反过来意味着,当我知道变量在1小时内重新润滑后发生变化时,我需要强制正则表达式重新编译,尽管/o修饰符.
更新:这里是我需要的例子/o- 没有它,每次循环迭代都会重新编译正则表达式(因而必须检查); 它不是:
$ perl -e '{for (my $i=0; $i<3; $i++) {
my $re = qr{$i}oix; $s="123"; $s =~ s/$re//;
print "i=$i; s=$s\n"; }}'
i=0; s=123
i=1; s=123
i=2; s=123
$ perl …Run Code Online (Sandbox Code Playgroud) 可能重复:
前缀双冒号"::"对类名的含义是什么?
我一直在寻找遗留的C++代码,它有这样的东西:
::putenv(local_tz_char);
::tzset();
Run Code Online (Sandbox Code Playgroud)
在函数调用中添加"::"的语法是什么意思?Google-fu让我失望了.
从perldoc perlobj(引用这个优秀的答案):
Run Code Online (Sandbox Code Playgroud)my $fred = Critter->find("Fred"); $fred->display("Height", "Weight");......以上代码大致相当于:
Run Code Online (Sandbox Code Playgroud)my $fred = Critter::find("Critter", "Fred"); Critter::display($fred, "Height", "Weight");
究竟有什么区别,除了错误检查以确保第一个参数是受祝福的对象或有效的类名?例如,为什么它大部分但不完全相同?
我已经在Perl构建Web scraper中工作了几年,并且考虑到垃圾邮件所代表的问题,以及如果例如Perl的LWP :: UserAgent可以处理它,那么如何让网页更容易抓取网页一杯JavaScript,我很惊讶没有人为它构建一个JS引擎.
我在这里错过了什么?
提前致谢.问候.
PS:我不是垃圾邮件发送者.只是好奇.
perl ×8
c++ ×2
coding-style ×2
syntax ×2
compilation ×1
die ×1
eval ×1
getopt ×1
getopt-long ×1
javascript ×1
modifier ×1
namespaces ×1
object ×1
oop ×1
perl-module ×1
redirect ×1
reflection ×1
regex ×1
stderr ×1
system ×1
system-calls ×1