我正在从LDAP服务器获取用户列表:
filter_person = Net::LDAP::Filter.eq("objectClass", "person")
treebase = "ou=people,dc=rocketfuel,dc=com"
ldap.search(:base => treebase, :filter => filter_person, :scope => Net::LDAP::SearchScope_SingleLevel, :attributes => ['uid', 'sshpublickey']) do |entry|
if users_uids.include?(entry.uid[0].to_s)
p entry.uid[0].to_s
end
end
此代码失败,但出现以下异常:
NoMethodError: undefined method `uid' for #<Net::LDAP::Entry:0x00000000074bf558>
这是预期的(一些用户没有UID)。但是我不太清楚为什么如果我把if
语句改为:
if entry.respond_to?(:uid) and users_uids.include?(entry.uid[0].to_s)
p entry.uid[0].to_s
end
我希望它能通过相同的错误(如if ... and
语句同时计算),但它实际上工作得很好。
为什么当我把entry.respond_to?(:uid)
添加到相同的条件表达式时,entry.uid[0]
没有引发相同的异常?
2条答案
按热度按时间laawzig21#
当
entry
上没有定义uid
时,调用entry.uid
会引发异常。如果entry
上没有定义uid
方法,则entry.respond_to?(:uid)
返回错误。这意味着它有效是因为
在第一个条件中计算为
false
,并且不再检查第二个条件,因为它不会改变结果。这是一个叫做Short-Circuit evaluation的特性,它存在于大多数语言中。
gojuced72#
And
操作不会在所有情况下执行两边在这个例子中,它首先计算左侧,只有当结果不同于
false
或nil
时,它才继续计算右侧部分。因此,如果
entry.respond_to?(:uid)
计算为nil
,则跳过右侧部分users_uids.include?(entry.uid[0].to_s)
。