Class: FixedRecord
- Inherits:
-
Object
- Object
- FixedRecord
- Defined in:
- lib/fixed_record.rb
Overview
Provides error-checked simplified access to a YAML data file
Constant Summary collapse
- VERSION =
"0.6.1"
Class Method Summary collapse
-
.data(filename, required: [], optional: [], singleton: false) ⇒ Object
Lazy load data from given filename creating accessors for top level attributes.
-
.validate(values, index) ⇒ Object
Override this to perform additional entries.
Class Method Details
.data(filename, required: [], optional: [], singleton: false) ⇒ Object
Lazy load data from given filename creating accessors for top level attributes
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/fixed_record.rb', line 12 def self.data( filename, required: [], optional: [], singleton: false ) required = required.map( &:to_s ) optional = optional.map( &:to_s ) throw ArgumentError, "Required and Optional names overlap" unless (required & optional).empty? # Although not necessary, the class_eval makes it easier to see # we are defining variables and methods in the context of the child class which # called us class_eval do # Use @x names for class variables to simplify / restrict access @filename = filename @valid_keys = Set.new( required ) @valid_keys.merge( optional ) @required_keys = Set.new( required ) @singleton = singleton # Load the data and create the methods... def self.load! return unless @items.nil? begin y = YAML.load_file( @filename ) rescue Errno::ENOENT raise rescue Psych::SyntaxError => error fname = File.basename(@filename) msg = error. if msg.include? @filename msg.sub!( @filename, fname ) msg = "#{error.class.name} #{msg}" else msg = "#{error.class.name} #{fname} #{error.}" end raise ArgumentError, msg end validate_structure( y, @singleton, @filename ) if @valid_keys.empty? # Grab keys from file if @singleton @valid_keys = y.keys elsif y.is_a?(Array) @valid_keys = y.first.keys @required_keys = @valid_keys elsif y.is_a?(Hash) @valid_keys = y[y.keys.first].keys @required_keys = @valid_keys end end if @singleton @items = y elsif y.is_a?(Array) @items = y.map.with_index do |values,i| validate_item( @valid_keys, @required_keys, values, i ) r = new r.instance_variable_set( :@values, values ) r end elsif y.is_a?(Hash) @items = Hash.new add_key = !@valid_keys.member?('key') y.each do |k,values| validate_item( @valid_keys, @required_keys, values, k ) values['key'] = k if add_key r = new r.instance_variable_set( :@values, values ) @items[k] = r end define_method( :key ) { @values['key'] } if add_key end create_methods( @valid_keys ) end # filename data was loaded from def self.filename @filename end # valid keys (as strings) def self.valid_names load! @valid_keys end end # class_eval if singleton class_eval do # class methods for singleton object def self.[](k) load! k = k.to_s raise ArgumentError, "#{k} is not a valid key" unless @valid_keys.member?(k) @items[k] end end # class_eval else # Add methods for Coillection based objects class << self include Enumerable end class_eval do def self.all load! @items end def self.each( &block ) all.each(&block) end def self.size all.size end def self.[]( k ) if all.is_a?(Hash) all[k.to_s] else nil # Arguably we could index the array, but if we did your code would smell... end end def self.has_item_key?( k ) if all.is_a?(Hash) all.has_key?( k ) else false end end end #class_eval # Only way I can find to alias class methods... class << self alias length size alias count size end end end |
.validate(values, index) ⇒ Object
Override this to perform additional entries. It gets passed the hash containing the values for each record. index is either a record index (0 based) or a key associated with the record
157 158 |
# File 'lib/fixed_record.rb', line 157 def self.validate( values, index ) end |