rfunk 0.1.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 +7 -0
- data/lib/rfunk/attribute.rb +72 -0
- data/lib/rfunk/either.rb +29 -0
- data/lib/rfunk/failure.rb +19 -0
- data/lib/rfunk/lazy.rb +25 -0
- data/lib/rfunk/none.rb +21 -0
- data/lib/rfunk/not_found_error.rb +4 -0
- data/lib/rfunk/option.rb +15 -0
- data/lib/rfunk/some.rb +25 -0
- data/lib/rfunk/success.rb +19 -0
- data/lib/rfunk/value.rb +24 -0
- data/lib/rfunk/version.rb +3 -0
- data/lib/rfunk.rb +16 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c539b96a759a551a6d9fbb57f06415dc09d0cb26
|
4
|
+
data.tar.gz: b5f8bb018a680fcfff0efcc0b18f9e32f4ba4dd5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 292cf72c0c5f89b49d368453f5183b0063da281ee86531832d07c61183336fb2dae11604a463f4efd19b7671e5e61ec0df9eb2a923152a15d09b6692e9bd82b2
|
7
|
+
data.tar.gz: 4b0b4dae55ee2f40a9a9a79f336a3f8cec5711058d55bec443b0be45e3afecde0ac45cb4053800e95e5820918a67d6a35bcf8ac82d6ef436873de71b61ebe33b
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module RFunk
|
2
|
+
module Attribute
|
3
|
+
ATTRIBUTES_VARIABLE_NAME = '@attributes'
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
attributes = self.class.instance_variable_get(ATTRIBUTES_VARIABLE_NAME)
|
11
|
+
|
12
|
+
options.each { |key, value|
|
13
|
+
raise_not_found(key, attributes)
|
14
|
+
|
15
|
+
type = attributes[key]
|
16
|
+
|
17
|
+
raise_expected_type(key, value, type)
|
18
|
+
|
19
|
+
self.instance_variable_set(variable_name(key), value)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def attribute(name, type)
|
25
|
+
add_attribute(name, type)
|
26
|
+
|
27
|
+
self.send :define_method, name do |value = nil|
|
28
|
+
if value
|
29
|
+
raise_expected_type(name, value, type)
|
30
|
+
create_immutable(variable_name(name), value)
|
31
|
+
else
|
32
|
+
Option(self.instance_variable_get(variable_name(name)))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def add_attribute(name, type)
|
40
|
+
attributes = self.instance_variable_get(ATTRIBUTES_VARIABLE_NAME) || {}
|
41
|
+
attributes[name] = type
|
42
|
+
self.instance_variable_set(ATTRIBUTES_VARIABLE_NAME, attributes)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def variable_name(name)
|
49
|
+
"@#{name}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_immutable(variable_name, value)
|
53
|
+
self.class.new.tap { |object|
|
54
|
+
self.instance_variables.select { |v| v != variable_name }.each { |v|
|
55
|
+
previous_value = self.instance_variable_get(v)
|
56
|
+
object.instance_variable_set(v, previous_value)
|
57
|
+
}
|
58
|
+
|
59
|
+
object.instance_variable_set(variable_name, value)
|
60
|
+
object.deep_freeze
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def raise_expected_type(name, value, type)
|
65
|
+
raise TypeError, "Expected a type of '#{type}' for attribute '#{name}'" unless value.instance_of?(type)
|
66
|
+
end
|
67
|
+
|
68
|
+
def raise_not_found(key, attributes)
|
69
|
+
raise RFunk::NotFoundError, "Attribute with name '#{key}' does not exist. The only available attributes are '#{attributes}'" unless attributes.key?(key)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/rfunk/either.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module RFunk
|
2
|
+
def Either(value)
|
3
|
+
if lambda?(value)
|
4
|
+
either_with_lambda(value)
|
5
|
+
else
|
6
|
+
either_with_value(value)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def lambda?(value)
|
13
|
+
value.respond_to?(:lambda?) and value.lambda?
|
14
|
+
end
|
15
|
+
|
16
|
+
def either_with_lambda(lambda)
|
17
|
+
RFunk::Success(lambda.call)
|
18
|
+
rescue => e
|
19
|
+
RFunk::Failure(e)
|
20
|
+
end
|
21
|
+
|
22
|
+
def either_with_value(value)
|
23
|
+
if value
|
24
|
+
RFunk::Success(value)
|
25
|
+
else
|
26
|
+
RFunk::Failure(value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/rfunk/lazy.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module RFunk
|
2
|
+
class Lazy
|
3
|
+
def initialize(lambda)
|
4
|
+
@lambda = lambda
|
5
|
+
@created = false
|
6
|
+
end
|
7
|
+
|
8
|
+
def value
|
9
|
+
Option(@value ||= lambda.call.tap { self.created = true })
|
10
|
+
end
|
11
|
+
|
12
|
+
def created?
|
13
|
+
created
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :lambda
|
19
|
+
attr_accessor :created
|
20
|
+
end
|
21
|
+
|
22
|
+
def Lazy(lambda)
|
23
|
+
Lazy.new(lambda)
|
24
|
+
end
|
25
|
+
end
|
data/lib/rfunk/none.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module RFunk
|
2
|
+
class None
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def value(default = nil)
|
6
|
+
Option(default)
|
7
|
+
end
|
8
|
+
|
9
|
+
def or(other)
|
10
|
+
Option(other)
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method, *arguments, &block)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def None(value = nil)
|
19
|
+
Option(value)
|
20
|
+
end
|
21
|
+
end
|
data/lib/rfunk/option.rb
ADDED
data/lib/rfunk/some.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module RFunk
|
2
|
+
class Some
|
3
|
+
attr_reader :value
|
4
|
+
|
5
|
+
def initialize(value)
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def or(_)
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(method, *arguments, &block)
|
14
|
+
Option(value.__send__(method, *arguments, &block))
|
15
|
+
end
|
16
|
+
|
17
|
+
def ==(other)
|
18
|
+
other.value == value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def Some(value)
|
23
|
+
Option(value)
|
24
|
+
end
|
25
|
+
end
|
data/lib/rfunk/value.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module RFunk
|
2
|
+
class Value
|
3
|
+
def initialize(value)
|
4
|
+
@value = value
|
5
|
+
end
|
6
|
+
|
7
|
+
def result
|
8
|
+
case value
|
9
|
+
when Some, None
|
10
|
+
value
|
11
|
+
else
|
12
|
+
Option(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def ==(other)
|
17
|
+
other.result == result
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :value
|
23
|
+
end
|
24
|
+
end
|
data/lib/rfunk.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'ice_nine'
|
3
|
+
require 'ice_nine/core_ext/object'
|
4
|
+
|
5
|
+
require 'rfunk/attribute'
|
6
|
+
require 'rfunk/option'
|
7
|
+
require 'rfunk/none'
|
8
|
+
require 'rfunk/some'
|
9
|
+
require 'rfunk/not_found_error'
|
10
|
+
require 'rfunk/lazy'
|
11
|
+
require 'rfunk/value'
|
12
|
+
require 'rfunk/failure'
|
13
|
+
require 'rfunk/success'
|
14
|
+
require 'rfunk/either'
|
15
|
+
|
16
|
+
include RFunk
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfunk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Falkowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ice_nine
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.11.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.11.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 10.1.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 10.1.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-given
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.5.4
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.5.4
|
55
|
+
description: See https://github.com/alexfalkowski/rfunk/blob/master/README.md
|
56
|
+
email:
|
57
|
+
- alexrfalkowski@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- lib/rfunk.rb
|
63
|
+
- lib/rfunk/attribute.rb
|
64
|
+
- lib/rfunk/either.rb
|
65
|
+
- lib/rfunk/failure.rb
|
66
|
+
- lib/rfunk/lazy.rb
|
67
|
+
- lib/rfunk/none.rb
|
68
|
+
- lib/rfunk/not_found_error.rb
|
69
|
+
- lib/rfunk/option.rb
|
70
|
+
- lib/rfunk/some.rb
|
71
|
+
- lib/rfunk/success.rb
|
72
|
+
- lib/rfunk/value.rb
|
73
|
+
- lib/rfunk/version.rb
|
74
|
+
homepage: https://github.com/alexfalkowski/rfunk
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.2.2
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Functional Programming in Ruby
|
98
|
+
test_files: []
|