rfunk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -0,0 +1,19 @@
1
+ module RFunk
2
+ class Failure < Value
3
+ def success?
4
+ false
5
+ end
6
+
7
+ def failure?
8
+ true
9
+ end
10
+
11
+ def or(value)
12
+ Failure(value)
13
+ end
14
+ end
15
+
16
+ def Failure(value)
17
+ Failure.new(value)
18
+ end
19
+ 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
@@ -0,0 +1,4 @@
1
+ module RFunk
2
+ class NotFoundError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module RFunk
2
+ def Option(value)
3
+ if nothing?(value)
4
+ None.instance
5
+ else
6
+ Some.new(value)
7
+ end
8
+ end
9
+
10
+ private
11
+
12
+ def nothing?(value)
13
+ value.nil? || (value.respond_to?(:empty?) && value.empty?) || value.is_a?(None)
14
+ end
15
+ end
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
@@ -0,0 +1,19 @@
1
+ module RFunk
2
+ class Success < Value
3
+ def success?
4
+ true
5
+ end
6
+
7
+ def failure?
8
+ false
9
+ end
10
+
11
+ def or(_)
12
+ self
13
+ end
14
+ end
15
+
16
+ def Success(value)
17
+ Success.new(value)
18
+ end
19
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module RFunk
2
+ VERSION = '0.1.0'
3
+ 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: []