2012-05-08 3 views
1

Я хочу itterate над массивом ключа, паров значений из почтовых параметров:рубин, если оценка заявления

Parameters: 
    {"utf8"=>"✓", 
    "authenticity_token"=>"c6VYssp33I075nfv1ViPty38+aZSkWM/jh6oll2pYS8=", 
    "permission"=> 
    {"employment_id"=>"7", 
    "organisation_level"=>"all_below", 
    "permissions"=>"view_permissions", 
    "users"=>"", 
    "organisation"=>"", 
    "functions"=>"", 
    "statistics"=>""}, 
    "commit"=>"Opslaan"} 

Я беру карту разрешения из этих параметров и попытаться обработать его. В основном я хочу проверить , если ключ не занят_ид, а значение присутствует.

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

end 

При запуске, если заявление в этом для каждого я столкнулся с каким-то странным поведением и Интересно, если кто-то может пролить свет на эту ситуацию

я закончил с этим, если заявление, он работает и оценивает, как я ожидаю. Он печатает только значение, когда значение не "" или nil и ключ разве employment_id

if(!(k.eql?"employment_id") && v.present?) 
    p v 
end 

Однако следующие два, если заявления не работают, как я ожидал. Оба печатают все значения. Они оценивают до true, хотя я думаю, что они не должны.

if(!k.eql?"employment_id" && v.present?) 
    p v 
end 

и

if !k.eql?"employment_id" && v.present? 
    p v 
end 
+1

Похоже на свою предшествующую вещь - ознакомьтесь с http://www.techotopia.com/index.php/Ruby_Operator_Precedence – ryan

ответ

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?) 

И здесь, "employment_id" && v.present? вычисляет true. По сути, вы задаете !k.eql?(true), который, будучи k, являющийся строкой, всегда принимает значение true (из-за отрицания).

Чтобы обойти проблему, обязательно используйте скобки. Предпочтительно связываться вы должны использовать их для вызовов методов, как так

k.eql?("employment_id") 

вместо того, чтобы как

(k.eql? "employment_id") 

Таким образом, вы сделаете это ясно, что аргументы метода и избежать двусмысленности, которые затем должны были быть решены старшинство. Я лично склонен только опускать скобку метода, если действительно ясно, что такое аргументы. Особенно в более сложных заявлениях, подобных вашим, просто не имеет смысла опускать их и, таким образом, уменьшать ясность.

+2

И как побочный комментарий, вы можете упростить свое утверждение до 'k! =" Employment_id "&& v. present? ' –

+0

, если я оцениваю' "employment_id" && "" .present ?, однако в моей рубиновой консоли это дает 'false' –

+0

. Вызов метода имеет более высокий приоритет, чем что-либо другое, а прямое сравнение имеет более высокий приоритет, чем' && '. Итак, мой пример выше эквивалентен '(k! =" Employment_id ") && (v.present?)'. В вашем примере «job_id» 'is truethy,' "" .present? "Является ложным. Таким образом, результат будет «ложным». См. Ссылку на @redspike выше для получения дополнительной информации о приоритете оператора в рубине. –

Смежные вопросы