callable 0.0.1 → 0.0.2

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
2
  SHA1:
3
- metadata.gz: 1ef39ede893ce0a86d29f34da19b77b7b2850090
4
- data.tar.gz: d05ad76db5f5914b825e8c23f2a4b6453c598c33
3
+ metadata.gz: e85b170016fdbc135bebf0884c38e5637907d77a
4
+ data.tar.gz: 040b7e0d547142f84b52b547594171f3fcaa29f6
5
5
  SHA512:
6
- metadata.gz: 00df6afe990ba3facb4d54ac73fb9ee4057086db2546afaba496eec83181ef7147e89b84a9691873357fab4f30adaa6a18ee3db371353618017879be35d0bde6
7
- data.tar.gz: 7ed99cd5b51200dbce8bd34192272af15bf7c7b9c627eb661f6647f6d8145a48ba31a6516c11e89bc3d1fb475a230a1517faeae890df41bf875a3be455c4f139
6
+ metadata.gz: 6ff80b6c79dd75efe33e43c156ef738354470e1a2ad61c67b05cef612e9abeb339900dce8c2f193bf69ed772d28bdb7902150f6fc9c1a77ee1f4a7e3867b24ab
7
+ data.tar.gz: 72ecb0cf755932c829ceeefc659b5960770836ed2fcdb377910c0283abf555cd0ca776d96de7aaba410e5a533a7357733ad58bc6464d99d13d6216563dbb88ce
data/README.md CHANGED
@@ -26,71 +26,108 @@ in one of two ways (don't forget to install the gem first).
26
26
  The first way is by invoking the callable method:
27
27
 
28
28
  ```ruby
29
- c = Callable( :ret_val )
30
- c.call
31
- => ret_val
29
+ c = Callable( :ret_val )
30
+ c.call
31
+ => ret_val
32
32
  ```
33
33
 
34
34
  Take into account that if you pass a callable object (such as a
35
35
  lambda), you'll get it back as the return value:
36
36
 
37
37
  ```ruby
38
- c = Callable( ->{ :ret_val } )
39
- c.call
40
- => ret_val
38
+ c = Callable( ->{ :ret_val } )
39
+ c.call
40
+ => ret_val
41
41
  ```
42
42
 
43
- The second way to use it is invoking the #callable directly on the object you
44
- want to be callable:
43
+ The gem also ships with a #callable? method thar returns true if the
44
+ object is callable and false if it's not.
45
45
 
46
46
  ```ruby
47
- c = :ret_val.callable
48
- c.call
49
- => ret_val
47
+ :not_callable.callable?
48
+ => false
49
+
50
+ ->{ :not_callable }.callable?
51
+ => true
50
52
  ```
51
53
 
52
- Like the example before, lambda, you'll get it back as the return value:
54
+ This is the same as saying
53
55
 
54
56
  ```ruby
55
- c = ->{ :ret_val }.callable
56
- c.call
57
- => ret_val
57
+ xxx.respond_to? :call
58
58
  ```
59
59
 
60
- The gem also ships with a #callable? method thar returns true if the
61
- object is callable and false if it's not.
60
+ But I felt it would be more illustrative of it's purpose.
61
+
62
+ ## Where to use it?
63
+
64
+ I think the main use for this library is handling actions as options.
65
+
66
+ For example, imagine we have a very reduced authorization library that provides a method called `do_if`.
67
+ This method receives:
68
+ - a symbol representing a permission name
69
+ - a Hash that represents the available authorization policies
70
+ - a block with the actions to perform
71
+
72
+ The premise is that the method will execute the block if the selected policy returns true when we send the `call` message.
73
+
74
+ Our first approach is:
62
75
 
63
76
  ```ruby
64
- :not_callable.callable?
65
- => false
66
- ->{ :not_callable }.callable?
67
- => true
77
+ def do_if(permission, policies=POLICIES)
78
+ yield if policies[permission].call
79
+ end
68
80
  ```
69
81
 
70
- This is the same as saying
82
+ So, if our POLICIES hash is:
71
83
 
72
84
  ```ruby
73
- xxx.respond_to? :call
85
+ POLICIES = {
86
+ development: -> { true }
87
+ }
88
+
89
+ do_if(:development) do
90
+ puts "Debugging"
91
+ end
92
+
93
+ # >> Debugging
74
94
  ```
75
95
 
76
- But I felt it would be more illustrative of it's purpose.
96
+ And if we switch the policy value:
97
+
98
+ ```ruby
99
+ POLICIES = {
100
+ development: -> { false }
101
+ }
102
+
103
+ do_if(:development) do
104
+ puts "Debugging"
105
+ end
106
+
107
+ # >>
108
+ ```
109
+
110
+ This allows us to have a lot of flexibility. But we could provide the user a way to say the same with less code:
111
+
112
+
113
+
77
114
 
78
- ## Where to use it?
79
115
 
80
- Let me say where to use this gem (with a very
81
- trivial example).
116
+ *******************************
117
+ Let me say where to use this gem with a very
118
+ trivial example.
82
119
 
83
120
  Imagine we have some class that admits an informer object that
84
121
  responds to the get_info method and returns a some information on a
85
122
  String.
86
123
 
87
124
  ```ruby
88
- class SomeClass
89
- attr_writer :informer
90
- def info
91
- @informer.get_info
125
+ class SomeClass
126
+ attr_writer :informer
127
+ def info
128
+ @informer.get_info
129
+ end
92
130
  end
93
- end
94
131
  ```
95
132
 
96
133
  If we want to use this "informer" object, we must define a new class
@@ -101,25 +138,25 @@ method "call", instead of "get_info", because we now can toss a simple
101
138
  lambda to substitute it. We can rewrite the code above like this:
102
139
 
103
140
  ```ruby
104
- class SomeClass
105
- attr_writer :informer
106
- def info
107
- @informer.call
141
+ class SomeClass
142
+ attr_writer :informer
143
+ def info
144
+ @informer.call
145
+ end
108
146
  end
109
- end
110
147
  ```
111
148
 
112
149
  And now we can define a class or module that responds to the call
113
150
  method. In that call method, we can get as fancy as we want:
114
151
 
115
152
  ```ruby
116
- module Informer
117
- def call
118
- # retrieve the information we need from wherever we want
119
- # maybe a web service
120
- # maybe a local file
153
+ module Informer
154
+ def call
155
+ # retrieve the information we need from wherever we want
156
+ # maybe a web service
157
+ # maybe a local file
158
+ end
121
159
  end
122
- end
123
160
  ```
124
161
 
125
162
  So, when we do:
@@ -149,7 +186,7 @@ thing like this:
149
186
 
150
187
  ```ruby
151
188
  something = SomeClass.new
152
- something.informer = Callable "No info available"
189
+ something.informer = Callable("No info available" )
153
190
  something.info
154
191
  ```
155
192
 
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'callable/version'
@@ -22,3 +21,5 @@ Gem::Specification.new do |spec|
22
21
  spec.add_development_dependency "rake", "~> 10.0"
23
22
  spec.add_development_dependency "matest", "~> 1.5"
24
23
  end
24
+
25
+
@@ -1,5 +1,23 @@
1
1
  require "callable/version"
2
2
 
3
3
  module Callable
4
- # Your code goes here...
4
+ def Callable( callable_or_not )
5
+ if callable_or_not.respond_to?(:call)
6
+ callable_or_not
7
+ else
8
+ proc { |*args| callable_or_not }
9
+ end
10
+ end
11
+
12
+ def callable
13
+ Callable(self)
14
+ end
15
+
16
+ def callable?
17
+ self.respond_to?(:call)
18
+ end
5
19
  end
20
+
21
+ ::Object.include(Callable)
22
+
23
+ puts "X" * 100
@@ -1,3 +1,3 @@
1
1
  module Callable
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,78 @@
1
+ require "spec_helper"
2
+
3
+ scope Callable do
4
+ spec "creates a callable object" do
5
+ @obj = :not_callable
6
+ @c = Callable(@obj)
7
+
8
+ @c.call == @obj
9
+ end
10
+
11
+ spec "leaves a callable object intact" do
12
+ @obj = -> { :callable }
13
+ @c = Callable(@obj)
14
+
15
+ @c == @obj
16
+ end
17
+
18
+ scope "#callable" do
19
+ spec "creates a callable object" do
20
+ @obj = :not_callable
21
+ @c = @obj.callable
22
+
23
+ @c.call == @obj
24
+ end
25
+
26
+ spec "leaves a callable object intact" do
27
+ @obj = -> { :callable }
28
+ @c = @obj.callable
29
+
30
+ @c == @obj
31
+ end
32
+
33
+ end
34
+
35
+ scope "#callable?" do
36
+ spec "returns true if the object responds to #call" do
37
+ @obj = -> { :callable }
38
+
39
+ @obj.callable?
40
+ end
41
+
42
+ spec "returns false if the object doesn't respond to #call" do
43
+ @obj = :not_callable
44
+
45
+ ! @obj.callable?
46
+ end
47
+ end
48
+
49
+ scope "arguments" do
50
+ spec "accepts arguments arguments" do
51
+ @obj = :not_callable
52
+ @c = Callable(@obj)
53
+
54
+ @c.call(1, 2, 3) == @obj
55
+ end
56
+
57
+ spec "passes the arguments on" do
58
+ @obj = -> (a, b) { a + " " + b }
59
+ @c = Callable(@obj)
60
+
61
+ @c.call("Call", "me") == "Call me"
62
+ end
63
+
64
+ spec "can pass any number of arguments to a proc" do
65
+ @obj = proc { |a, b| a + " " + b }
66
+ @c = Callable(@obj)
67
+
68
+ @c.call("Call", "me", "now") == "Call me"
69
+ end
70
+
71
+ spec "passes the arguments on" do
72
+ @obj = -> (*args) { args.join(" ") }
73
+ @c = Callable(@obj)
74
+
75
+ @c.call("Call", "me", "now") == "Call me now"
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ require "callable"
2
+
3
+ Matest.configure do |config|
4
+ config.use_color
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: callable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Federico Iachetti
@@ -68,6 +68,8 @@ files:
68
68
  - callable.gemspec
69
69
  - lib/callable.rb
70
70
  - lib/callable/version.rb
71
+ - spec/callable_spec.rb
72
+ - spec/spec_helper.rb
71
73
  homepage: ''
72
74
  licenses:
73
75
  - MIT
@@ -92,4 +94,6 @@ rubygems_version: 2.4.5
92
94
  signing_key:
93
95
  specification_version: 4
94
96
  summary: It allows you to define callable objects.
95
- test_files: []
97
+ test_files:
98
+ - spec/callable_spec.rb
99
+ - spec/spec_helper.rb