localstore 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []