我需要确定Perl哈希是否具有给定密钥,但该密钥将映射到undef值.具体来说,这样做的动机是看到布尔标志在使用getopt()哈希引用时是否传入其中.我已经搜查两本网站和谷歌,exists()而defined()似乎不适用的情况下,他们只看到如果给定键的值是不确定的,他们不检查哈希实际上有钥匙.如果我是RTFM,请指出解释此问题的手册.
所以,我们有代码:
class Foo
def bar
puts "Before existent: #{(defined? some_variable)}"
puts "Before not_existent: #{(defined? nonexistent_variable)}"
raise "error"
some_variable = 42
rescue
puts "exception"
ensure
puts "Ensure existent: #{(defined? some_variable)}"
puts "Ensure not_existent: #{(defined? nonexistent_variable)}"
end
end
Run Code Online (Sandbox Code Playgroud)
并从irb调用它:
> Foo.new.bar
Run Code Online (Sandbox Code Playgroud)
而且,这将返回:
Before existent:
Before not_existent:
exception
Ensure existent: local-variable
Ensure not_existent:
=> nil
Run Code Online (Sandbox Code Playgroud)
现在问题 - 为什么?我们之前提出异常而不是some_variable定义.为什么这样工作?为什么some_variable在ensure块中定义?(顺便说一下,它定义为零)
更新: 感谢@Max的回答,但如果我们更改代码以使用实例变量:
class Foo
def bar
puts "Before existent: #{(defined? @some_variable)}"
puts "Before not_existent: #{(defined? @nonexistent_variable)}"
raise …Run Code Online (Sandbox Code Playgroud) clang 3.9增加了-Wall一个-Wexpansion-to-defined产生的警告
产生'定义'的宏扩展具有未定义的行为
如果defined在#if表达式之外使用,包括随后在#if表达式中使用的宏的情况.例如以下代码
// in some file:
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))
// possibly in another file:
#if defined(__clang__) || HAS_GNU
/* ... */
#endif
Run Code Online (Sandbox Code Playgroud)
产生
test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
#if defined(__clang__) || HAS_GNU
^
test.cc:3:18: note: expanded from macro 'HAS_GNU'
#define HAS_GNU (defined(__GNUC__) && !defined(__clang__))
^
test.cc:5:27: warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
test.cc:3:40: note: expanded from macro 'HAS_GNU' …Run Code Online (Sandbox Code Playgroud) 在尝试分配变量并在Perl中的一个操作中测试它的定义时,就像在if条件中有用一样,我似乎很自然地写:
if ( defined my $thing = $object->get_thing ) {
$thing->do_something;
}
Run Code Online (Sandbox Code Playgroud)
就我的理解而言,右向列表运算符defined的优先级低于赋值的优先级,因此我希望上面的代码等效于:
if ( defined ( my $thing = $object->get_thing ) ) {
$thing->do_something;
}
Run Code Online (Sandbox Code Playgroud)
虽然后者,带括号的代码确实有效,但前者会产生以下致命错误:"无法在标量赋值中修改已定义的运算符".
添加括号并不是什么大不了的事,但我很想理解为什么第一个版本不起作用,例如什么样的"东西" defined是什么,它的优先级是什么?
另请参阅:文档中的哪些内容表示测试readdir的定义性?.(不重复;只是密切相关.)
许多人将下面的循环视为惯用语:
while (defined(my $file = readdir($dir)) {
...
}
Run Code Online (Sandbox Code Playgroud)
代替:
while (my $file = readdir($dir)) {
...
}
Run Code Online (Sandbox Code Playgroud)
因为假设文件名只是"0"(零),所以应该使用后一版本,它应该终止循环,而当没有更多文件时它返回'undef'.
但是在过去的某个时刻,这个测试已经defined()停止了必要 - 似乎有一些特殊的案例代码允许后一个版本无论如何都能工作.
我想知道这是如何工作的?
奇怪的是,如果我更换调用readdir()与调用foo()来代替:
sub foo
{
my ($dir) = @_;
return readdir($dir);
}
while (my $file = foo($dir)) {
...
}
Run Code Online (Sandbox Code Playgroud)
那么代码确实做了我期望的事情,并在找到名为"0"的文件时终止循环.
(在MacOS X 10.5.6上使用Perl 5.8.9进行测试)
请看下面的代码:
use strict;
use warnings;
print "subroutine is defined\n" if defined &myf;
myf();
sub myf
{
print "called myf\n";
}
undef &myf;
#myf();
print "now subroutine is defined\n" if defined &myf;
Run Code Online (Sandbox Code Playgroud)
输出是
subroutine is defined
called myf
Run Code Online (Sandbox Code Playgroud)
第一个print语句可以打印,这是否意味着解释器(或编译器?)看得更远并看到子例程定义?如果是这样,为什么它没有看到undef &myf;第二个print陈述?
谢谢
如果我将常数设为=''; 如何检查是否有内部的东西?
defined(),并不像我希望的isset()那样工作,因为它被定义
不适用于常量
有什么简单的方法吗?
我正在写一个django模板,我想区分一个上下文变量的存在与它是无,空等等.我做了我的功课,看起来非常难.具体来说,这就是我想要做的
view 1:
...
if some_condition = True:
context['letters'] = ['a', 'b', 'c'] # The list might also be empty or None in some cases
else
context['numbers'] = [1, 2, 3] #This list might be empty or None in some cases
Template
...
<ul>
{% if letters %}
{% for x in letter %}
<li>{{x}}</li>
{%endfor%}
{% else %}
{%for x in numbers%}
<li>{{x}}</li>
{%endfor%}
</ul>
Run Code Online (Sandbox Code Playgroud)
使用{% if %}is dicey,因为如果letters不存在或列表为空则失败.我想使用letters即使它是空的(但在上下文中定义)
我有一个内置的过滤器同样的问题default …
我有一个配置文件,我在程序的早期包含并设置它
define('BASE_SLUG','/shop');
Run Code Online (Sandbox Code Playgroud)
我稍后会在这些行中包含另一个文件
echo BASE_SLUG;
if (defined(BASE_SLUG)) {
echo ' - yes';
} else {
echo ' - no';
}
Run Code Online (Sandbox Code Playgroud)
我的输出是
/shop - no
Run Code Online (Sandbox Code Playgroud)
这怎么可能? BASE_SLUG有价值,/shop我可以回应它,但一行之后,它说它没有定义