如何区分未传递的参数和传递错误值的参数?
我试图找出在 Perl 中区分未传递参数和参数已作为 0 传递的情况的最佳方法,因为它们对我来说意味着不同的事情。
(通常我喜欢这种歧义性,但在这种情况下,我正在生成 SQL,所以我想用 NULL 替换未定义的参数,但将 0 保留为 0。)
所以这就是歧义性:
sub mysub {
my $arg1 = shift;
if ($arg1){
print "arg1 could have been 0 or it could have not been passed.";
}
}
到目前为止,这是我最好的解决方案..但我觉得有点丑。我想知道你是否能想出一种更干净的方法,或者这对你来说是否可行:
sub mysub {
my $arg1 = (defined shift) || "NULL";
if ($arg1 ne "NULL"){
print "arg1 came in as a defined value.";
}
else {
print "arg1 came in as an undefined value (or we were passed the string 'NULL')";
}
}
I am trying to figure the best way to differeniate in Perl between cases where an argument has not been passed, and where an argument has been passed as 0, since they mean different things to me.
(Normally I like the ambiguity, but in this case I'm generating SQL so I want to replace undefined args with NULL, but leave 0 as 0.)
So this is the ambiguity:
sub mysub {
my $arg1 = shift;
if ($arg1){
print "arg1 could have been 0 or it could have not been passed.";
}
}
And so far, this is my best solution... but I think it is a little ugly. I'm wondering if you can think of a cleaner way or if this looks OK to you:
sub mysub {
my $arg1 = (defined shift) || "NULL";
if ($arg1 ne "NULL"){
print "arg1 came in as a defined value.";
}
else {
print "arg1 came in as an undefined value (or we were passed the string 'NULL')";
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
以下是如何处理所有可能情况的示例:(
@_
是函数的参数数组。此处将其与1
进行比较,计算元素数量我故意避免使用shift
,因为它会改变@_
,这需要我们存储@_
的原始大小。某处。)Here's an example of how you can handle all the possible cases:
(
@_
is the array of arguments to your function. Comparing it to1
here is counting the number of elements in the array. I'm intentionally avoidingshift
, as it alters@_
, which would require us to store the original size of@_
somewhere.)怎么样:
更新:我添加了检查是否有任何内容传入。但这仅在您需要单个参数时才有用。如果您想获取多个参数并需要区分未定义和省略的参数,请采用哈希值。
顺便说一句:如果您必须执行任何步骤来清理您的参数,请不要自己执行。看看cpan,尤其是Params::Validate
What about:
Update: I added the check if there was anything passed in at all. But that can only be useful if you are expecting a single parameter. If you would like to get multiple params and need to differentiate between undefined and omitted parameters, take a hash.
And btw: If you have to do any steps to sanitize your params, don't do it yourself. Have a look at cpan and especially Params::Validate
就我个人而言,我喜欢保留
undef
来表示 NULL - 它与 DBI 占位符/DBIx::Class/SQL::Abstract 的所有功能相匹配,以及将其设置为字符串"NULL" 的风险
的问题是您会意外插入字符串,而不是NULL
本身。如果您使用的是最新版本的 Perl(5.10 或更高版本),请查看特别方便的“定义或”运算符
//
和//=
用于处理参数。关于 SQL,如果你想生成 SQL 字符串,你可能会得到这样的结果:
编辑(回答有关 NULL 和 undef 的问题):
使用带有占位符的 DBI 句柄:
DBIx::Class
DBIx::Class - 相同的原理 - 传入一个未定义在数据库中创建
NULL
的值:personally I like keeping
undef
to represent NULLs - it matches what DBI placeholders/DBIx::Class/SQL::Abstract all do, and the risk with setting it to be the string"NULL"
is that you will accidentally insert the string, rather thanNULL
itself.If you're using a recent version of Perl (5.10 or above), then check out the 'defined-or' operators
//
and//=
which are particularly handy for processing arguments.regarding the SQL, if you want to generate the SQL string, you could end up with something like this:
edit (to answer the bit about NULL and undef):
Using DBI handles with placeholders:
DBIx::Class
DBIx::Class - same principle - pass in an undef value to create a
NULL
in the database:唯一确定的方法是检查
@_
的长度以查看该槽中是否有参数。当还存在强制参数时,这可能会被视为有点复杂,但事实并非如此。这是许多对象访问器中使用的模式:The only way to be sure is to inspect the length of
@_
to see if there was an argument in that slot. This can be seen as a little complicated when there are also mandatory arguments, but it doesn't have to be. Here's a pattern used in a lot of object accessors:地图是你的朋友。尝试一下:
为了添加更多色彩,我喜欢使用哈希作为参数,以提高代码清晰度并消除记住参数顺序的重要性。所以重写它看起来像这样:(
更新:正确处理 0,然后再次使用 // 运算符。)
map is your friend. Try this:
To add a little more color, I've become a fan of using a hash as the arguments for code clarity and to remove the importance of remembering arugment ordering. So rewritten it would look like this:
(Updated: to handle 0 correctly and then again to use the // operator.)