I want to itterate over a array of key,value pairs from post parameters:
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"c6VYssp33I075nfv1ViPty38+aZSkWM/jh6oll2pYS8=",
"permission"=>
{"employment_id"=>"7",
"organisation_level"=>"all_below",
"permissions"=>"view_permissions",
"users"=>"",
"organisation"=>"",
"functions"=>"",
"statistics"=>""},
"commit"=>"Opslaan"}
I take the permission map out of these parameters and try to process it. Basically I want to check if the key isn’t employment_id and the value is present.
params.each do |k,v|
if(!(k.eql?"employment_id") && v.present?)
p v
end
end
When running the if statement in this for each I ran into some strange behaviour and I wonder if someone can shine some light on this situation
I ended up with this if statement, it works and evaluates like I expect it to. It only prints the values when the value is not "" or nil and the key isnt employment_id
if(!(k.eql?"employment_id") && v.present?)
p v
end
However, The following 2 if statements dont work as I expect. Both print all values. They evaluate to true while I think they shouldn’t.
if(!k.eql?"employment_id" && v.present?)
p v
end
and
if !k.eql?"employment_id" && v.present?
p v
end
The cause of your confusion is the priority of operations, especially in thew face of you omitting parenthesis. In your case, the statements are evaluated as follows:
And here,
"employment_id" && v.present?evaluates totrue. So essentially, you are asking!k.eql?(true)which, withkbeing a string always evaluates totrue(because of the negation).To circumvent the issue, make sure to use parenthesis appropriately. Preferrably you should use them for method calls like so
instead of like
That way, you make it clear what the method arguments are and avoid ambiguities which are then needed to be resolved by precedence. I personally tend to only omit method parenthesis if it is really clear what the arguments are. Especially in more complex statements like yours, it just doesn’t make much sense to omit them and thus reduce clarity.