localstore 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 75a0f31d41f3a25e79784f76c5801a7805203113
4
+ data.tar.gz: c707c8a66d4f2501fc3602bf3eebd41c56d1d3d8
5
+ SHA512:
6
+ metadata.gz: 633d2c10d8b1eb91101e7180c85f13b6d8981a4d5336bce373ca0d8e67c00df377efedf39c3458335b2f8ae40011f770ad9065f8183d7690270374c1d4f00395
7
+ data.tar.gz: dbff138aa1c5c0f01f58ed7a1ed757ebfc8d1ac40755b3ecf2bf4918732d7de99812edf5fbb5f27175b4a6d0a8337dae64810e5ff739109a2e270c4fcb9a9273
@@ -0,0 +1,20 @@
1
+ # File: Rakefile
2
+ # Time-stamp: <2018-12-13 11:06:32>
3
+ # Copyright (C) 2018 Pierre Lecocq
4
+ # Description: LocalStore rake tasks
5
+
6
+ task default: :spec
7
+
8
+ # Spec
9
+
10
+ require 'rspec/core/rake_task'
11
+
12
+ RSpec::Core::RakeTask.new :spec
13
+
14
+ # Yard
15
+
16
+ require 'yard'
17
+
18
+ YARD::Rake::YardocTask.new do |t|
19
+ t.files = ['lib/**/*.rb']
20
+ end
@@ -0,0 +1,119 @@
1
+ # File: localstore.rb
2
+ # Time-stamp: <2018-12-14 08:16:38>
3
+ # Copyright (C) 2018 Pierre Lecocq
4
+ # Description: LocalStore module for classes
5
+
6
+ # Provides a class level local data store with namespaces support.
7
+ #
8
+ # API:
9
+ #
10
+ # When calling `localstore` at the top of a class definition, class and instance methods are created automatically:
11
+ #
12
+ # - <namespace>_store(key, value) to store data in the local store
13
+ # - <namespace>_fetch(key = nil) to fetch data from the local store
14
+ # - <namespace>_flush to flush data from the local store
15
+ #
16
+ # @example Local storage from class and instance methods
17
+ #
18
+ # require 'localstore'
19
+ #
20
+ # class TestLocalStore
21
+ # extend LocalStore
22
+ #
23
+ # # Initialize namespace
24
+ # localstore :test
25
+ # end
26
+ #
27
+ # # Class methods#
28
+ # TestLocalStore.test_store :hello, 'world'
29
+ # p TestLocalStore.test_fetch :hello
30
+ # p TestLocalStore.test_fetch
31
+ # TestLocalStore.test_flush
32
+ # p TestLocalStore.test_fetch
33
+ #
34
+ #
35
+ # # Instance methods
36
+ # obj = TestLocalStore.new
37
+ # obj.test_store :hello2, 'world2'
38
+ # p obj.test_fetch :hello2
39
+ # p obj.test_fetch
40
+ # obj.test_flush
41
+ # p obj.test_fetch
42
+ #
43
+ module LocalStore
44
+ # Library name
45
+ NAME = 'localstore'.freeze
46
+
47
+ # Semantic version number
48
+ VERSION = [0, 5, 0].join '.'
49
+
50
+ # @!visibility private
51
+ attr_reader :_local_store
52
+
53
+ # Create a new namespace in the local store and create dynamic class methods
54
+ # to interact with the store
55
+ #
56
+ # @param namespace [Symbol, String] namespace to create
57
+ def localstore(namespace)
58
+ localstores namespace
59
+ end
60
+
61
+ # Create multiple new namespaces in the local store and create dynamic class
62
+ # methods to interact with the store
63
+ #
64
+ # @param namespaces [Array<Symbol>, Array<String>] namespaces to create
65
+ def localstores(*namespaces)
66
+ namespaces.each do |namespace|
67
+ @_local_store ||= {}
68
+ @_local_store[namespace] ||= {}
69
+
70
+ create_class_methods namespace
71
+ create_instance_methods namespace
72
+ end
73
+ end
74
+
75
+ # Create class metods according to the namespace
76
+ #
77
+ # @api private
78
+ #
79
+ # @param namespace [Symbol, String]
80
+ def create_class_methods(namespace)
81
+ self.class.send :define_method, "#{namespace}_store" do |key, value|
82
+ @_local_store[namespace][key] = value
83
+ end
84
+
85
+ self.class.send :define_method, "#{namespace}_fetch" do |key = nil|
86
+ return @_local_store[namespace] if key.nil?
87
+
88
+ @_local_store[namespace].fetch key
89
+ end
90
+
91
+ self.class.send :define_method, "#{namespace}_flush" do
92
+ @_local_store[namespace] = {}
93
+ end
94
+ end
95
+
96
+ # Create instance methods according to a namespace.
97
+ # They are only proxy methods to class methods
98
+ #
99
+ # @api private
100
+ #
101
+ # @param namespace [Symbol, String]
102
+ def create_instance_methods(namespace)
103
+ define_method "#{namespace}_store" do |key, value|
104
+ self.class.send "#{namespace}_store", key, value
105
+ end
106
+
107
+ define_method "#{namespace}_fetch" do |key = nil|
108
+ self.class.send "#{namespace}_fetch", key
109
+ end
110
+
111
+ define_method "#{namespace}_flush" do
112
+ self.class.send "#{namespace}_flush"
113
+ end
114
+ end
115
+ end
116
+
117
+ # https://6ftdan.com/allyourdev/2015/02/24/writing-methods-for-both-class-and-instance-levels/
118
+ # http://railstic.com/2011/06/dynamically-defining-methods-with-define_method/
119
+ # http://paulsturgess.co.uk/blog/2018/01/09/ruby-metaprogramming-define-method-and-instance-exec/
@@ -0,0 +1,58 @@
1
+ # File: localstore_spec.rb
2
+ # Time-stamp: <2018-12-14 08:08:11>
3
+ # Copyright (C) 2018 Pierre Lecocq
4
+ # Description: LocalStore module spec
5
+
6
+ require_relative '../lib/localstore'
7
+
8
+ describe LocalStore do
9
+ before :all do
10
+ class TestLocalStore
11
+ extend LocalStore
12
+
13
+ localstore :test
14
+ end
15
+ end
16
+
17
+ it 'checks class methods' do
18
+ expect(TestLocalStore).to respond_to :test_store
19
+ expect(TestLocalStore).to respond_to :test_fetch
20
+ expect(TestLocalStore).to respond_to :test_flush
21
+ end
22
+
23
+ it 'checks instance methods' do
24
+ obj = TestLocalStore.new
25
+
26
+ expect(obj).to respond_to :test_store
27
+ expect(obj).to respond_to :test_fetch
28
+ expect(obj).to respond_to :test_flush
29
+ end
30
+
31
+ it 'checks local store from class methods calls' do
32
+ TestLocalStore.test_store :key_1, '1'
33
+ TestLocalStore.test_store :key_2, '2'
34
+
35
+ expect(TestLocalStore.test_fetch(:key_1)).to be == '1'
36
+ expect(TestLocalStore.test_fetch(:key_2)).to be == '2'
37
+ expect(TestLocalStore.test_fetch).to be == { key_1: '1', key_2: '2' }
38
+
39
+ TestLocalStore.test_flush
40
+
41
+ expect(TestLocalStore.test_fetch).to be == {}
42
+ end
43
+
44
+ it 'checks local store from instance methods calls' do
45
+ obj = TestLocalStore.new
46
+
47
+ obj.test_store :key_3, '3'
48
+ obj.test_store :key_4, '4'
49
+
50
+ expect(obj.test_fetch(:key_3)).to be == '3'
51
+ expect(obj.test_fetch(:key_4)).to be == '4'
52
+ expect(obj.test_fetch).to be == { key_3: '3', key_4: '4' }
53
+
54
+ obj.test_flush
55
+
56
+ expect(obj.test_fetch).to be == {}
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: localstore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Pierre Lecocq
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Provides a class level local data store with namespaces support
14
+ email: pierre.lecocq@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Rakefile
20
+ - lib/localstore.rb
21
+ - spec/localstore_spec.rb
22
+ homepage: https://github.com/pierre-lecocq/localstore
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.6.14
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Local data store
46
+ test_files: []