insane_hook 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0a61856275cac8c83baf51f5dbe739af495c2086
4
- data.tar.gz: 04f39eb108182f93f346afbd2c164ec36a421fda
2
+ SHA256:
3
+ metadata.gz: 02b68a08a81d3f28cfad66779ed793df6ce08fcc200f56395f2c4d6bea82d786
4
+ data.tar.gz: c141a6ee66ed0766c6e36301f020fbdb2ceb4350e17f021b6fd03f7cf543c9fb
5
5
  SHA512:
6
- metadata.gz: 576f92cee691387c45cc6f06971ade6c8eb2c7113ae14a90e277d732266eae6b2a01656b3d24cc4805e67f7ee421b2e03f40825fbf657937c00206ce2f2a8933
7
- data.tar.gz: 40c9e53c80c015a4cf4646449ac7dd41629205e5045ced29ab172ad8967f5139f267334ca2c83a2d9a87dd2faa054fcb86718e2bf0a0de7c9059c25a4217401b
6
+ metadata.gz: d4280e7a961f0c9d5d442ba93f89dc4bf7da836f96380883306051f12a1227423e69424b9881903c5936bca5b6a4f2dfcbfb758250a4c87a3e749ec2ad4bc172
7
+ data.tar.gz: 793c51f4be50e4b7af99cba480c64c9fb604230d598428b83b71ff0d6ad9818ec18337b25483f5c0dff930dff3d83b7f8d0c200900f5578dfde36e661b982188
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- insane_hook (0.3.0)
4
+ insane_hook (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -32,4 +32,4 @@ DEPENDENCIES
32
32
  rspec (~> 3.0)
33
33
 
34
34
  BUNDLED WITH
35
- 1.16.1
35
+ 1.16.2
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Enjoy the enforcing-DSL of this command-patterny gem.
4
4
 
5
+ ## Current version
6
+
7
+ 0.4.0
8
+
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
@@ -21,47 +25,57 @@ Or install it yourself as:
21
25
  ## Usage
22
26
 
23
27
  ```ruby
24
- class YeOldeTaske
25
- include InsaneHook
26
- need :some_required_arg
27
- allow :some_optional_arg
28
+ class YeOldeTaske < InsaneHook
29
+ requires :some_required_arg
30
+ fallbacks :some_optional_arg
28
31
 
29
32
  call do
30
- # attr_readers are available for:
31
- # - some_required_arg
32
- # - some_optional_arg
33
33
  result "meaningful value"
34
34
  end
35
35
  end
36
-
37
- YeOldeTaske.new # => InsaneHook::MissingArgumentError
38
-
39
- task = YeOldeTaske.new(some_required_arg: "input") # => YeOldeTaske instance
40
- task.result # => raises InsaneHook::CommandNotRunError
41
- task.call # => YeOldeTaske instance
42
- task.result # => "meaningful value"
43
36
  ```
44
37
 
38
+ Is equivalent to:
39
+
45
40
  ```ruby
46
41
  class YeOldeTaske
47
- include InsaneHook
48
- need :some_required_arg
49
- allow :some_optional_arg
50
42
 
51
- call do
52
- # attr_readers are available for:
53
- # - some_required_arg
54
- # - some_optional_arg
43
+ def self.call(**args)
44
+ new(**args).call
55
45
  end
56
- end
57
46
 
58
- task = YeOldeTaske.new(some_required_arg: 7).call
59
- task.result # => nil
47
+ attr_reader :some_required_arg, :some_optional_arg
48
+ def initialize(some_required_arg:, some_optional_arg: nil)
49
+ @some_required_arg = some_required_arg
50
+ @some_optional_arg = some_optional_arg
51
+ end
60
52
 
61
- # Also
62
- task = YeOldeTaske.call(some_required_arg: 7)
53
+ def call
54
+ result "meaningful value"
55
+ self
56
+ end
57
+
58
+ def result(arg = InsaneHook::NO_ARG)
59
+ if arg == InsaneHook::NO_ARG
60
+ if instance_variable_defined?(:@result)
61
+ @result
62
+ else
63
+ raise InsaneHook::CommandNotRunError
64
+ end
65
+ else
66
+ @result = arg
67
+ end
68
+ end
69
+
70
+ end
63
71
  ```
64
72
 
73
+
74
+ ## Design decisions
75
+ 1. Usage of `call` is idiomatic Ruby. Procs and method objects respond to `call`, so we are extending an existing Ruby pattern.
76
+ 2. Commands should not return anything, but if you are forced to check a result, then set the result to a single object and work off of that object, for instance if you want to use the command as one of the clauses of a case statement (in which case the result would be a boolean)
77
+ 3. Composition is usually better than Inheritance, especially in a language that doesn't support multiple inheritance. Here we need to use inheritance because we are completely taking over both the `.new` and the `#initialize` methods, meaning the object does not truly belong to the person writing the code.
78
+
65
79
  ## Development
66
80
 
67
81
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/insane_hook.rb CHANGED
@@ -1,78 +1,25 @@
1
+ require "insane_hook/class_methods"
1
2
  require "insane_hook/version"
3
+ require "insane_hook/errors"
2
4
 
3
- module InsaneHook
4
- ARGS_VAR = :@@_command
5
- REQUIRED_ARGS = :required
6
- OPTIONAL_ARGS = :optional
7
- RESULT_VAR = :@_result
8
- NO_ARG = :_no_value
9
- class CommandNotRunError < StandardError ; end
10
- class MissingArgumentError < StandardError ; end
5
+ class InsaneHook
6
+ include InsaneHook::Errors
7
+ include InsaneHook::Constants
11
8
 
12
- def self.included(mod)
13
- mod.class_variable_set(::InsaneHook::ARGS_VAR, {REQUIRED_ARGS => [], OPTIONAL_ARGS => []})
14
- mod.extend(ClassMethods)
15
- mod.define_singleton_method(:need, mod.instance_method(:_need))
16
- mod.define_singleton_method(:allow, mod.instance_method(:_allow))
17
- mod.define_singleton_method(:call, mod.instance_method(:_call))
9
+ def self.inherited(subclass)
10
+ subclass.class_variable_set(ARGS_VAR, {REQUIRED_ARGS => [], OPTIONAL_ARGS => []})
11
+ subclass.extend(InsaneHook::ClassMethods)
18
12
  end
19
13
 
20
14
  def result(value=NO_ARG)
21
15
  if value == NO_ARG
22
- if instance_variable_defined?(::InsaneHook::RESULT_VAR)
23
- instance_variable_get(::InsaneHook::RESULT_VAR)
16
+ if instance_variable_defined?(RESULT_VAR)
17
+ instance_variable_get(RESULT_VAR)
24
18
  else
25
19
  raise CommandNotRunError
26
20
  end
27
21
  else
28
- instance_variable_set(::InsaneHook::RESULT_VAR, value)
29
- end
30
- end
31
-
32
- def _need(key)
33
- fail "#{key} is not a symbol" unless key.is_a? Symbol
34
- args = self.class_variable_get(::InsaneHook::ARGS_VAR)
35
- args[REQUIRED_ARGS] << key
36
- self.class_variable_set(::InsaneHook::ARGS_VAR, args)
37
- end
38
-
39
- def _allow(key)
40
- fail "#{key} is not a symbol" unless key.is_a? Symbol
41
- args = self.class_variable_get(::InsaneHook::ARGS_VAR)
42
- args[OPTIONAL_ARGS] << key
43
- self.class_variable_set(::InsaneHook::ARGS_VAR, args)
44
- end
45
-
46
- def _call(**args, &block)
47
- if block_given?
48
- raise "Block cannot take arguments" if block.arity > 0
49
- raise "call method already defined" if self.instance_methods.include?(:call)
50
- define_method(:call) do
51
- result(nil)
52
- instance_eval(&block)
53
- self
54
- end
55
- else
56
- new(**args).call
57
- end
58
-
59
- end
60
-
61
- module ClassMethods
62
- def new(**args)
63
- obj = self.allocate
64
- self.class_variable_get(::InsaneHook::ARGS_VAR)[REQUIRED_ARGS].each do |var|
65
- value = args.fetch(var) { raise(::InsaneHook::MissingArgumentError, "#{var} not provided in #{self.class}") }
66
- obj.instance_variable_set("@#{var}", value)
67
- obj.class.class_eval{attr_reader var}
68
- end
69
- self.class_variable_get(::InsaneHook::ARGS_VAR)[OPTIONAL_ARGS].each do |var|
70
- value = args.fetch(var, nil)
71
- obj.instance_variable_set("@#{var}", value)
72
- obj.class.class_eval{attr_reader var}
73
- end
74
- obj.send :initialize
75
- obj
22
+ instance_variable_set(RESULT_VAR, value)
76
23
  end
77
24
  end
78
25
  end
@@ -0,0 +1,53 @@
1
+ require "insane_hook/constants"
2
+ require "insane_hook/errors"
3
+
4
+ class InsaneHook
5
+ module ClassMethods
6
+ include Constants
7
+ include Errors
8
+
9
+ def new(**args)
10
+ obj = self.allocate
11
+ self.class_variable_get(ARGS_VAR)[REQUIRED_ARGS].each do |var|
12
+ value = args.fetch(var) { raise(MissingArgumentError, "#{var} not provided in #{self.class}") }
13
+ obj.instance_variable_set("@#{var}", value)
14
+ obj.class.class_eval{attr_reader var}
15
+ end
16
+ self.class_variable_get(ARGS_VAR)[OPTIONAL_ARGS].each do |var|
17
+ value = args.fetch(var, nil)
18
+ obj.instance_variable_set("@#{var}", value)
19
+ obj.class.class_eval{attr_reader var}
20
+ end
21
+ obj.send :initialize
22
+ obj
23
+ end
24
+
25
+ def requires(key)
26
+ fail "#{key} is not a symbol" unless key.is_a? Symbol
27
+ args = self.class_variable_get(ARGS_VAR)
28
+ args[REQUIRED_ARGS] << key
29
+ self.class_variable_set(ARGS_VAR, args)
30
+ end
31
+
32
+ def fallbacks(key)
33
+ fail "#{key} is not a symbol" unless key.is_a? Symbol
34
+ args = self.class_variable_get(ARGS_VAR)
35
+ args[OPTIONAL_ARGS] << key
36
+ self.class_variable_set(ARGS_VAR, args)
37
+ end
38
+
39
+ def call(**args, &block)
40
+ if block_given?
41
+ raise "Block cannot take arguments" if block.arity > 0
42
+ raise "call method already defined" if self.instance_methods.include?(:call)
43
+ define_method(:call) do
44
+ result(nil)
45
+ instance_eval(&block)
46
+ self
47
+ end
48
+ else
49
+ new(**args).call
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,9 @@
1
+ class InsaneHook
2
+ module Constants
3
+ ARGS_VAR = :@@_command
4
+ REQUIRED_ARGS = :required
5
+ OPTIONAL_ARGS = :optional
6
+ RESULT_VAR = :@_result
7
+ NO_ARG = :_no_value
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ class InsaneHook
2
+ module Errors
3
+ class CommandNotRunError < StandardError
4
+ end
5
+ class MissingArgumentError < StandardError
6
+ end
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
- module InsaneHook
2
- VERSION = "0.3.0"
1
+ class InsaneHook
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: insane_hook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aldric Giacomoni, Ahmad Ragab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-23 00:00:00.000000000 Z
11
+ date: 2018-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,6 +72,9 @@ files:
72
72
  - bin/setup
73
73
  - insane_hook.gemspec
74
74
  - lib/insane_hook.rb
75
+ - lib/insane_hook/class_methods.rb
76
+ - lib/insane_hook/constants.rb
77
+ - lib/insane_hook/errors.rb
75
78
  - lib/insane_hook/version.rb
76
79
  homepage: https://github.com/Trevoke/insane-hook
77
80
  licenses:
@@ -94,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
97
  version: '0'
95
98
  requirements: []
96
99
  rubyforge_project:
97
- rubygems_version: 2.6.14
100
+ rubygems_version: 2.7.3
98
101
  signing_key:
99
102
  specification_version: 4
100
103
  summary: Another implementation of the command pattern that provides a DSL.