Ruby if语句评估

Ben*_*ate 1 ruby

我想对post参数中的一组键值对进行迭代:

Parameters:
  {"utf8"=>"?",
  "authenticity_token"=>"c6VYssp33I075nfv1ViPty38+aZSkWM/jh6oll2pYS8=", 
  "permission"=>
    {"employment_id"=>"7", 
     "organisation_level"=>"all_below", 
     "permissions"=>"view_permissions", 
     "users"=>"", 
     "organisation"=>"", 
     "functions"=>"", 
     "statistics"=>""}, 
  "commit"=>"Opslaan"} 
Run Code Online (Sandbox Code Playgroud)

我从这些参数中取出权限映射并尝试处理它.基本上我想检查密钥是否不是employment_id并且值是否存在.

params.each do |k,v|
  if(!(k.eql?"employment_id") && v.present?)
   p v
  end

end
Run Code Online (Sandbox Code Playgroud)

当在每个中运行if语句时,我遇到了一些奇怪的行为,我想知道是否有人可以对这种情况有所了解

我最终得到了这个if语句,它的工作和评估就像我期望的那样.它仅在值不是""或nil且密钥不是时才打印值employment_id

if(!(k.eql?"employment_id") && v.present?)
  p v
end 
Run Code Online (Sandbox Code Playgroud)

但是,以下2个if语句不能正常工作.两者都打印所有值.他们评价,true而我认为他们不应该.

if(!k.eql?"employment_id" && v.present?)
  p v 
end 
Run Code Online (Sandbox Code Playgroud)

和

if !k.eql?"employment_id" && v.present?
  p v 
end 
Run Code Online (Sandbox Code Playgroud)

Hol*_*ust 5

混淆的原因是操作的优先级,尤其是在省略括号的情况下.在您的情况下,语句的评估如下:

if(!k.eql?"employment_id" && v.present?)
# equivalent to 
if (!(k.eql?("employment_id" && v.present?)))

if !k.eql?"employment_id" && v.present?
# equivalent to 
if !k.eql?("employment_id" && v.present?)
Run Code Online (Sandbox Code Playgroud)

在这里,"employment_id" && v.present?评估为true.所以基本上,你要问的!k.eql?(true)是,k作为一个字符串总是评估true(因为否定).

要避免此问题,请确保正确使用括号.您最好将它们用于方法调用

k.eql?("employment_id")
Run Code Online (Sandbox Code Playgroud)

而不是像

(k.eql? "employment_id")
Run Code Online (Sandbox Code Playgroud)

这样,您可以清楚地了解方法参数是什么,并避免出现需要通过优先级解决的歧义.如果真的很清楚参数是什么,我个人倾向于只省略方法括号.特别是在像你这样的更复杂的陈述中,省略它们并因此降低清晰度没有多大意义.

  • 作为旁注,你可以将你的陈述简化为`k!="employment_id"&& v.present?` (2认同)