MemoryRecord
Introduction
A simple library that handles a few records easily. With this library can flexibly managed immutable data.
Installation
Install as a standalone gem
$ gem install memory_record
Or install within application using Gemfile
$ bundle add memory_record
$ bundle install
Examples
Basic usage
class Language
include MemoryRecord
memory_record [
{key: :lisp, author: "John McCarthy" },
{key: :c, author: "Dennis Ritchie" },
{key: :ruby, author: "Yukihiro Matsumoto" },
]
def
"Mr. #{}"
end
end
Language[:ruby].key # => :ruby
Language[:ruby].code # => 2
Language[:ruby]. # => "Yukihiro Matsumoto"
Language[:ruby]. # => "Mr. Yukihiro Matsumoto"
Language.keys # => [:lisp, :c, :ruby]
Language.collect(&:author) # => ["John McCarthy", "Dennis Ritchie", "Yukihiro Matsumoto"]
How to turn as an array?
Enumerable extended, so that each method is available
Foo.each { |e| ... }
Foo.collect { |e| ... }
How do I submit a form to select in Rails?
form.collection_select(:selection_code, Foo, :code, :name)
Is the reference in subscripts slow?
Since it has a hash internally using the key value as a key, it can be acquired with O (1).
Foo[1].name # => "A"
Foo[:a].name # => "A"
Instances always react to code and key
object = Foo.first
object.key # => :a
object.code # => 1
How do I add a method to an instance?
For that, I am creating a new class so I need to define it normally
name method is special?
If name is not defined, it defines a name method that returns key.to_s
to_s method is defined?
Alias of name, to_s is defined.
If there is no key, use fetch to get an error
Foo.fetch(:xxx) # => <KeyError: ...>
The following are all the same
Foo[:xxx] || :default # => :default
Foo.fetch(:xxx, :default} # => :default
Foo.fetch(:xxx) { :default } # => :default
Use fetch_if to ignore if the key is nil
Foo.fetch_if(nil) # => nil
Foo.fetch_if(:a) # => #<Foo:... @attributes={...}>
Foo.fetch_if(:xxx) # => <KeyError: ...>
How to refer to other keys
class Foo
include MemoryRecord
memory_record [
{key: :a, other_key: :x},
{key: :b, other_key: :y},
{key: :c, other_key: :z},
]
class << self
def lookup(v)
super || invert_table[v]
end
private
def invert_table
@invert_table ||= inject({}) {|a, e| a.merge(e.other_key => e) }
end
end
end
Foo[:a] == Foo[:x] # => true
Foo[:b] == Foo[:y] # => true
Foo[:c] == Foo[:z] # => true
How can I prohibit the hash key from being attr_reader automatically?
attr_reader: false
I think that it is better to use it when you want to make it difficult to access easily.
class Foo
include MemoryRecord
memory_record attr_reader: false do
[
{x: 1, y: 1, z: 1},
]
end
end
Foo.first.x rescue $! # => #<NoMethodError: undefined method `x' for #<Foo:0x007fb2c710eda8>>
Foo.first.y rescue $! # => #<NoMethodError: undefined method `y' for #<Foo:0x007fb2c710eda8>>
Foo.first.z rescue $! # => #<NoMethodError: undefined method `z' for #<Foo:0x007fb2c710eda8>>
attr_reader: :y
class Foo
include MemoryRecord
memory_record attr_reader: {only: :y} do
[
{x: 1, y: 1, z: 1},
]
end
end
Foo.first.x rescue $! # => #<NoMethodError: undefined method `x' for #<Foo:0x007fcc861ff108>>
Foo.first.y rescue $! # => 1
Foo.first.z rescue $! # => #<NoMethodError: undefined method `z' for #<Foo:0x007fcc861ff108>>
attr_reader: :y
class Foo
include MemoryRecord
memory_record attr_reader: {except: :y} do
[
{x: 1, y: 1, z: 1},
]
end
end
Foo.first.x rescue $! # => 1
Foo.first.y rescue $! # => #<NoMethodError: undefined method `y' for #<Foo:0x007ff033895e88>>
Foo.first.z rescue $! # => 1
*** How to decide code yourself?
class Foo
include MemoryRecord
memory_record [
{code: 1, key: :a, name: "A"},
{code: 2, key: :b, name: "B"},
{code: 3, key: :c, name: "C"},
]
end
Foo.collect(&:code) # => [1, 2, 3]
It is not recommended to specify it explicitly. It is useful only when refactoring legacy code with compatibility in mind.