fn_space 0.1.0 → 1.0.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 +4 -4
- data/README.md +128 -17
- data/lib/fn_space.rb +10 -36
- data/lib/fn_space/assignable.rb +8 -0
- data/lib/fn_space/export.rb +5 -0
- data/lib/fn_space/import.rb +21 -0
- data/lib/fn_space/utils.rb +15 -0
- metadata +28 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef2eda95f4d90d23f7159493efab4a5d2e27443c
|
4
|
+
data.tar.gz: f14a79bff5994467498973e2470b6a770ca952cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d28c17beb0190f6e029dc9ec2434659cddd3658d0345d3c468535b320ed62ad004ce67955b442dea5e675c70f58fd61f1da92bc544b212572c0acfbd980e17be
|
7
|
+
data.tar.gz: d92fd1d315563e6093b9a7982e71157069bb34f4c1479d1181c794f3e3d6f92aa6ac5d3d9f50ef453962d4a2185539203f5f09f8befd57796d6865b5bb9d7c01
|
data/README.md
CHANGED
@@ -1,36 +1,147 @@
|
|
1
1
|
# FnSpace
|
2
2
|
|
3
|
-
|
3
|
+
FnSpace is a space where functions can be treated as first class objects. It
|
4
|
+
provides import and export helpers that prioritize functions and utility
|
5
|
+
methods to enable functional paradigms.
|
4
6
|
|
5
7
|
## Example
|
6
8
|
|
7
9
|
``` ruby
|
10
|
+
# my_awsome_project/formula.rb
|
8
11
|
require 'fn_space'
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
fn_space(:Formula) do |import, exports|
|
14
|
+
pi = 3.14
|
15
|
+
exports.circ = ->(r) { 2 * pi * r }
|
16
|
+
exports.area = ->(r) { pi * r ** 2 }
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
``` ruby
|
21
|
+
# my_awsome_project/other_file.rb
|
22
|
+
require 'fn_space'
|
23
|
+
require_relative 'formula'
|
24
|
+
|
25
|
+
fn_space do |import|
|
26
|
+
fn1, fn2 = import.(:area, :circ).from Formula
|
27
|
+
fn1.(8) # 200.96
|
28
|
+
fn2.(8) # 50.24
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
### `fn_space(const = nil) { |import, exports| block }`
|
35
|
+
|
36
|
+
`fn_space` is a global method that executes a block passed to it in an
|
37
|
+
anonymous module. It passes two arguments to the provided block, `import` and
|
38
|
+
`exports`.
|
39
|
+
|
40
|
+
It optionally takes a new constant's name as it first argument, which will then
|
41
|
+
be used to store any properties added to the `exports` OpenStruct.
|
42
|
+
|
43
|
+
### `import.(*names).from Source`
|
44
|
+
|
45
|
+
`import.()` can be used to import properties from a source. If only a single
|
46
|
+
property is requested then only a single value will be return, otherwise an
|
47
|
+
array will be.
|
48
|
+
|
49
|
+
``` ruby
|
50
|
+
MagicNumbers = Struct.new(:a, :b, :c).new(5, 7, 19)
|
51
|
+
|
52
|
+
fn_space do |import|
|
53
|
+
b = import.(:b).from MagicNumbers
|
54
|
+
c, a = import.(:c, :a).from MagicNumbers
|
55
|
+
|
56
|
+
a + b + c # 31
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
### `import.methods.(*names).from Source`
|
61
|
+
|
62
|
+
`import.methods.()` can be used to import methods from a source as method objects.
|
63
|
+
|
64
|
+
``` ruby
|
65
|
+
fn_space do |import|
|
66
|
+
tan = import.methods.(:tan).from Math
|
67
|
+
sin, cos = import.methods.(:sin, :cos).from Math
|
68
|
+
pi = Math::PI
|
14
69
|
|
15
|
-
|
16
|
-
|
17
|
-
|
70
|
+
tan.(0) # 0
|
71
|
+
sin.(pi/2) # 1.0
|
72
|
+
cos.(pi) # -1.0
|
18
73
|
end
|
74
|
+
```
|
75
|
+
|
76
|
+
## Utils
|
77
|
+
|
78
|
+
### `mod.()`
|
79
|
+
|
80
|
+
`mod.()` creates a new anonymous module with an `assign` singleton method that
|
81
|
+
can be used to create singleton methods in a chain.
|
82
|
+
|
83
|
+
``` ruby
|
84
|
+
fn_space do |import|
|
85
|
+
mod = import.(:mod).from FnSpace::Utils
|
86
|
+
foo = mod.()
|
87
|
+
.assign(:add) { |a, b| a + b }
|
88
|
+
.assign(:take) { |a, b| a - b }
|
89
|
+
|
90
|
+
foo.add(3, 4) # 7
|
91
|
+
foo.take(5, 2) # 3
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### `struct.(hash)`
|
96
|
+
|
97
|
+
`struct.()` takes a hash and creates a new anonymous module with properties
|
98
|
+
taken from the hash.
|
99
|
+
|
100
|
+
``` ruby
|
101
|
+
fn_space do |import|
|
102
|
+
struct = import.(:struct).from FnSpace::Utils
|
103
|
+
crds = struct.(x: 0.5, y: 1.5, z: -1.0)
|
104
|
+
crds.x + crds.y + crds.z # 1.0
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
### `chain.(value)`
|
109
|
+
|
110
|
+
`chain.()` wraps around a value and can be used to chain functions to be applied
|
111
|
+
to the value. It does this by providing the following methods:
|
112
|
+
|
113
|
+
* `>>` - Applies a function to the value and replaces the value with the result.
|
114
|
+
* `<<` - Applies a function to the value but does not replace the value.
|
115
|
+
* `|` - Applies a function to the chain object itself.
|
116
|
+
* `value` - Returns the value.
|
19
117
|
|
20
|
-
|
21
|
-
|
22
|
-
}
|
118
|
+
Function arguments have their `#to_proc` method called first such that symbols
|
119
|
+
can be used to call methods on an object.
|
23
120
|
|
24
|
-
|
25
|
-
|
26
|
-
|
121
|
+
``` ruby
|
122
|
+
fn_space do |import|
|
123
|
+
chain = import.(:chain).from FnSpace::Utils
|
27
124
|
|
28
|
-
|
125
|
+
double = ->(v) { v * 2 }
|
126
|
+
log = ->(v) { puts v }
|
29
127
|
|
30
|
-
|
128
|
+
res = chain.(3) >> double >> :next << log >> double << log >> :next | :value
|
129
|
+
# 7
|
130
|
+
# 14
|
131
|
+
puts res # 15
|
31
132
|
end
|
133
|
+
```
|
134
|
+
|
135
|
+
### `apply_send.(*args)`
|
32
136
|
|
33
|
-
|
137
|
+
`apply_send.()` can be used to apply arguments to an object's `send` method.
|
138
|
+
This can useful used in conjunction with the `chain` utility.
|
139
|
+
|
140
|
+
``` ruby
|
141
|
+
fn_space do |import|
|
142
|
+
chain, send = import.(:chain, :apply_send).from FnSpace::Utils
|
143
|
+
chain.(2) >> send.(:**, 3) >> send.(:/, 4) | :value # 2
|
144
|
+
end
|
34
145
|
```
|
35
146
|
|
36
147
|
## Installation
|
data/lib/fn_space.rb
CHANGED
@@ -1,36 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(names)
|
12
|
-
@names = names
|
13
|
-
end
|
14
|
-
|
15
|
-
def from(constant)
|
16
|
-
obj = ::Object.const_get(constant)
|
17
|
-
is_hash = obj.respond_to?(:has_key?)
|
18
|
-
functions = @names.map { |m| is_hash ? obj[m].to_proc : obj.method(m) }
|
19
|
-
functions.length == 1 ? functions.first : functions
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Exporter
|
24
|
-
def initialize(obj)
|
25
|
-
@obj = obj
|
26
|
-
end
|
27
|
-
|
28
|
-
def to(constant)
|
29
|
-
if ::Object.const_defined?(constant)
|
30
|
-
::Object.const_get(constant).merge!(@functions)
|
31
|
-
else
|
32
|
-
::Object.const_set(constant, @functions)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
1
|
+
require 'ostruct'
|
2
|
+
require_relative 'fn_space/utils'
|
3
|
+
require_relative 'fn_space/import'
|
4
|
+
require_relative 'fn_space/export'
|
5
|
+
|
6
|
+
def fn_space(const = nil, &b)
|
7
|
+
exports = OpenStruct.new
|
8
|
+
Module.new.instance_exec(FnSpace::Import, exports, &b)
|
9
|
+
FnSpace::Export.(const, FnSpace::Utils.struct.(exports.to_h)) if const
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'utils'
|
2
|
+
chain = FnSpace::Utils.chain
|
3
|
+
mod = FnSpace::Utils.mod
|
4
|
+
|
5
|
+
first_or_all = ->(array) { array.length == 1 ? array.first : array }
|
6
|
+
map = ->(array) { ->(map_fn) { array.map(&map_fn) } }
|
7
|
+
send_map_fn = ->(obj) { ->(name) { obj.send(name) } }
|
8
|
+
method_map_fn = ->(obj) { ->(name) { obj.method(name) } }
|
9
|
+
|
10
|
+
importer = ->(names, map_fn) do
|
11
|
+
mod.().assign(:from) do |source|
|
12
|
+
chain.(source) >> map_fn >> map.(names) >> first_or_all | :value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
import = ->(*names) { importer.(names, send_map_fn) }
|
17
|
+
import_methods = ->(*names) { importer.(names, method_map_fn) }
|
18
|
+
|
19
|
+
FnSpace::Import = mod.()
|
20
|
+
.assign(:call, &import)
|
21
|
+
.assign(:methods){import_methods}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'assignable'
|
2
|
+
|
3
|
+
mod = ->(&b) { Module.new(&b).extend(FnSpace::Assignable) }
|
4
|
+
struct = ->(hash) { hash.reduce(mod.()) { |obj, (k, v)| obj.assign(k){v} } }
|
5
|
+
apply_send = ->(method, *args) { ->(obj) { obj.send(method, *args) } }
|
6
|
+
|
7
|
+
chain = ->(value) do
|
8
|
+
monad = mod.()
|
9
|
+
.assign(:>>) { |fn| value = fn.to_proc.(value); monad }
|
10
|
+
.assign(:<<) { |fn| fn.to_proc.(value); monad }
|
11
|
+
.assign(:|) { |fn| fn.to_proc.(monad) }
|
12
|
+
.assign(:value) { value }
|
13
|
+
end
|
14
|
+
|
15
|
+
FnSpace::Utils = struct.(mod: mod, struct: struct, apply_send: apply_send, chain: chain)
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fn_space
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max White
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
12
|
-
dependencies:
|
11
|
+
date: 2015-10-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.1.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.1.0
|
13
33
|
description:
|
14
34
|
email: mushishi78@gmail.com
|
15
35
|
executables: []
|
@@ -19,6 +39,10 @@ files:
|
|
19
39
|
- LICENSE.txt
|
20
40
|
- README.md
|
21
41
|
- lib/fn_space.rb
|
42
|
+
- lib/fn_space/assignable.rb
|
43
|
+
- lib/fn_space/export.rb
|
44
|
+
- lib/fn_space/import.rb
|
45
|
+
- lib/fn_space/utils.rb
|
22
46
|
homepage: https://github.com/mushishi78/fn_space
|
23
47
|
licenses:
|
24
48
|
- MIT
|
@@ -42,5 +66,5 @@ rubyforge_project:
|
|
42
66
|
rubygems_version: 2.4.8
|
43
67
|
signing_key:
|
44
68
|
specification_version: 4
|
45
|
-
summary: A Ruby class for explicit
|
69
|
+
summary: A Ruby class for explicit importing and exporting
|
46
70
|
test_files: []
|