我刚刚看完一个railscast episode #189并且正在使用bit_mask在users表中存储一个值。我正在尝试实现同样的事情,但是当我通过irb测试时,我遇到了错误。首先,有人可以解释这实际上是什么。我知道第一行正在做什么,第二行的一部分
ROLES = %w[admin moderator author]
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum
end
def roles
ROLES.reject { |r| ((roles_mask || 0) & 2**ROLES.index(r)).zero? }
end
在irb中我得到了这个:
irb(main):013:0> ROLES = %w[admin moderator author]
(irb):13: warning: already initialized constant ROLES
=> ["admin", "moderator", "author"]
irb(main):014:0> roles = %w[admin author]
=> ["admin", "author"]
irb(main):015:0> roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum
NoMethodError: undefined method `sum' for [1, 4]:Array
答案 0 :(得分:3)
它在irb中不起作用的原因是sum
是在ActiveSupport中定义的,而不是ruby的标准库。如果你require 'active_support'
首先(或只是使用脚本/控制台),它将在irb。
roles=
的作用是根据ROLES
数组(item)中角色的顺序将角色数组转换为位掩码,然后将该位掩码保存为role_mask
。例如,["admin", "author"]
将变为5(二进制为0b101
)。不在ROLES
中的角色将被忽略(例如["admin", "bla"]
与["admin"]
相同)。
roles
的作用是将保存的位掩码转换回角色数组。
答案 1 :(得分:2)
他使用数字作为位字段。在二进制中,数字的每个位代表一个标志。通过添加2 ^ n,您可以设置位n,通过减去2 ^ n就可以清除它(假设它是在第一位设置的。)
Array#sum方法可能特定于Rails,或Ruby 1.9的一部分。它所做的就是获取数组中的每个元素并将它们相加。你可以这样做。
roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0){|m,n| m + n}