Advertisement
Guest User

Untitled

a guest
Dec 18th, 2018
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.14 KB | None | 0 0
  1. module Me
  2. module ActsAsBitfield
  3.  
  4. def self.included(base)
  5. base.send :extend, ClassMethods
  6. end
  7.  
  8. module ClassMethods
  9. def acts_as_bitfield(bitfield, attrs, virtual_attrs = {})
  10. unless respond_to? :bitfields
  11. class_eval { cattr_accessor :bitfields }
  12. self.bitfields = {}
  13. end
  14. b = 0
  15. self.bitfields[bitfield.to_sym] = attrs.inject({}) do |attr_values, attr|
  16. attr_values[attr.to_sym] = 2 ** b
  17. b +=
  18. end
  19.  
  20. virtual_attrs.each do |attr, values|
  21. self.bitfields[bitfield.to_sym][attr.to_sym] = virtuals(bitfield, attr, values)
  22. end
  23.  
  24. define_method("get_#{bitfield}") do
  25. self.bitfields[bitfield.to_sym].select{|attr, value| get_bit_into_bitfield(bitfield, value) == 1 }.keys
  26. end
  27.  
  28. # Create bit accessors
  29. self.bitfields[bitfield.to_sym].each_key do |attr|
  30. value = self.bitfields[bitfield.to_sym][attr]
  31.  
  32. define_method("#{bitfield}_#{attr}") do
  33. get_bit_into_bitfield(bitfield, value)
  34. end
  35.  
  36. define_method("#{bitfield}_#{attr}?") do
  37. get_bit_into_bitfield(bitfield, value) == 1
  38. end
  39.  
  40. define_method("#{bitfield}_#{attr}=") do |flag|
  41. set_bit_into_bitfield(bitfield, value, flag)
  42. end
  43. end
  44.  
  45. puts self.bitfields
  46. # Virtual bit accessors
  47. def virtuals(bitfield, attr, values)
  48. value = values.inject(self.bitfields[bitfield.to_sym][values[0]]) do |memo, v|
  49. memo & self.bitfields[bitfield.to_sym][v]
  50. end
  51. value
  52. end
  53.  
  54. send :include, InstanceMethods
  55. end
  56. end
  57.  
  58. module InstanceMethods
  59. private
  60.  
  61. def get_bit_into_bitfield(bitfield, value)
  62. (self.send(bitfield) & value == 0) ? 0 : 1
  63. end
  64.  
  65. def set_bit_into_bitfield(bitfield, value, flag)
  66. write_attribute(bitfield, self.send(bitfield) | value)
  67. write_attribute(bitfield, self.send(bitfield) ^ value) unless ActiveRecord::Type::Boolean.new.type_cast_from_user(flag)
  68. end
  69. end
  70. end
  71. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement