eg 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 474897a20982cd13215fb44ad94ef33f1b707c946b7c980b019ecba5ac35ce5d
4
+ data.tar.gz: d2da974a757adde708cfdd71883ee4b601826017051f6356fad2731781aead49
5
+ SHA512:
6
+ metadata.gz: ed4bd7fa4c2a37a42a8096a54191a702b560084be91f4f56165cf4b372eb0d86993bc43109e3cc0a2e80a25d0af6861ea197b4d20d542a0ec22ee04e3220b444
7
+ data.tar.gz: acb74c22ace39c14888c56b7ca8ee20e364053f26555f6f028c7f6759911562b6474b284cfcc69957312af49cc4680540a6ec0e4f410b14ccb727ee65a70bcc7
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
@@ -0,0 +1,4 @@
1
+ 1.0 2019-06-15
2
+ --------------
3
+
4
+ * First working version
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 digital-fabric
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,101 @@
1
+ # EG - Prototype based objects for Ruby
2
+
3
+ [INSTALL](#installing-eg) |
4
+ [USAGE](#using-eg)
5
+
6
+ ## What is EG
7
+
8
+ EG is a small gem that lets you create objects based on a prototype instead of a
9
+ class definition. Eg is useful for creating singletons, mockups, service or
10
+ factory objects, or simply for writing simple scripts without resorting to the
11
+ `class MyClass; ...; end; my_object = MyClass.new` dance.
12
+
13
+ ```ruby
14
+ require 'eg'
15
+
16
+ greeter = EG.(
17
+ greet: -> (name) { puts "Hello, #{name}!" }
18
+ )
19
+
20
+ greeter.greet('world')
21
+ ```
22
+
23
+ ## Installing EG
24
+
25
+ ```bash
26
+ $ gem install eg
27
+ ```
28
+
29
+ Or add it to your Gemfile, you know the drill.
30
+
31
+ ## Using EG
32
+
33
+ The EG module is a callable that accepts a single hash argument containing
34
+ method prototypes and constant definitions. You can define methods, constants
35
+ and instance variables:
36
+
37
+ ```ruby
38
+ o = EG.(
39
+ foo: -> { @bar },
40
+ '@bar': :baz,
41
+ VALUE: 42
42
+ )
43
+
44
+ o.foo #=> :baz
45
+ o::VALUE #=> 42
46
+ ```
47
+
48
+ ### defining methods
49
+
50
+ Any prototype key that does not begin with an upper-case letter or `@` is
51
+ considered a method. If the value is a proc or responds to `#to_proc`, it will
52
+ be used as the method body. Otherwise, EG will wrap the value in a proc that
53
+ returns it:
54
+
55
+ ```ruby
56
+ o = EG.(
57
+ foo: -> { :bar },
58
+ bar: :baz
59
+ )
60
+
61
+ o.foo #=> :bar
62
+ o.bar #=> :baz
63
+ ```
64
+
65
+ ### defining constants
66
+
67
+ Constants are defined using keys that begin with an upper-case letter:
68
+
69
+ ```ruby
70
+ o = EG.(
71
+ AnswerToEverything: 42
72
+ )
73
+
74
+ o::AnswerToEverything #=> 42
75
+ ```
76
+
77
+ Care should be taken to always qualify constants when accessing them from
78
+ prototype methods by prefixing them with `self::`:
79
+
80
+ ```ruby
81
+ o = EG.(
82
+ A: 1,
83
+ a: ->(x) { self::A + x }
84
+ )
85
+
86
+ o.a(2) #=> 3
87
+ ```
88
+
89
+ ### defining instance variables
90
+
91
+ Instance variables are defined using keys that begin with an `@`:
92
+
93
+ ```ruby
94
+ o = EG.(
95
+ '@count': 0,
96
+ incr: -> { @count += 1 }
97
+ )
98
+
99
+ o.incr #=> 1
100
+ o.incr #=> 2
101
+ ```
data/TODO.md ADDED
@@ -0,0 +1 @@
1
+ - Rename gem to eg
@@ -0,0 +1,18 @@
1
+ require_relative('lib/eg/version')
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'eg'
5
+ s.version = EG::VERSION
6
+ s.licenses = ['MIT']
7
+ s.summary = 'EG: Prototype-based objects for Ruby'
8
+ s.author = 'Sharon Rosner'
9
+ s.email = 'ciconia@gmail.com'
10
+ s.files = `git ls-files`.split
11
+ s.homepage = 'http://github.com/digital-fabric/eg'
12
+ s.metadata = { "source_code_uri" => "https://github.com/digital-fabric/eg" }
13
+ s.rdoc_options = ["--title", "EG", "--main", "README.md"]
14
+ s.extra_rdoc_files = ["README.md", "CHANGELOG.md"]
15
+
16
+ s.add_runtime_dependency 'modulation', '~> 0.20'
17
+ s.add_development_dependency 'minitest', '5.11.3'
18
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'modulation/gem'
4
+
5
+ export_default :EG
6
+
7
+ # EG object creation functionality
8
+ module EG
9
+ RE_CONST = /^[A-Z]/.freeze
10
+ RE_ATTR = /^@(.+)$/.freeze
11
+
12
+ # Creates an object from its prototype hash
13
+ # @param hash [Hash] prototype hash
14
+ # @return [Module] created object
15
+ def self.call(hash)
16
+ Module.new.tap do |m|
17
+ s = m.singleton_class
18
+ hash.each do |k, v|
19
+ if k =~ RE_CONST
20
+ m.const_set(k, v)
21
+ elsif k =~ RE_ATTR
22
+ m.instance_variable_set(k, v)
23
+ elsif v.respond_to?(:to_proc)
24
+ s.define_method(k) { |*args| instance_exec(*args, &v) }
25
+ else
26
+ s.define_method(k) { v }
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.to_proc
33
+ ->(hash) { EG.call(hash) }
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EG
4
+ VERSION = '1.0'
5
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'modulation'
4
+ require 'minitest/autorun'
5
+
6
+ EG = import '../lib/eg'
7
+
8
+ class EGTest < MiniTest::Test
9
+ def test_that_eg_can_define_methods
10
+ m = EG.(a: ->(x) { x + 1 }, b: ->(x) { x * 2})
11
+ assert_equal(4, m.a(3))
12
+ assert_equal(6, m.b(3))
13
+ end
14
+
15
+ def test_that_eg_can_define_constants
16
+ m = EG.(A: 1, B: 2)
17
+ assert_equal(1, m::A)
18
+ assert_equal(2, m::B)
19
+ end
20
+
21
+ def test_that_eg_constants_are_accessible_from_methods
22
+ m = EG.(A: 1, a: ->(x) { x + self::A })
23
+ assert_equal(4, m.a(3))
24
+ end
25
+
26
+ def test_that_eg_accepts_attributes
27
+ m = EG.("@foo": 'bar', getattr: -> { @foo })
28
+
29
+ assert_equal('bar', m.getattr)
30
+ end
31
+
32
+ def test_the_works
33
+ effect = ->(f) {
34
+ EG.(
35
+ map: ->(g) { effect.(->(*x) {g.(f.(*x))}) },
36
+ run_effects: ->(*x) { f.(*x) },
37
+ join: ->(*x) { f.(*x) },
38
+ chain: ->(g) { effect.(f).map(g).join() }
39
+ )
40
+ }
41
+
42
+ msgs = []
43
+ f_zero = ->() {
44
+ msgs << 'Starting with nothing'
45
+ 0
46
+ }
47
+ zero = effect.(f_zero)
48
+ increment = ->(x) { x + 1 }
49
+ one = zero.map(increment)
50
+
51
+ assert_equal([], msgs)
52
+ assert_equal(1, one.run_effects)
53
+ assert_equal(['Starting with nothing'], msgs)
54
+
55
+ msgs.clear
56
+ double = ->(x) { x * 2 }
57
+ cube = ->(x) { x**3 }
58
+ eight = zero.map(increment).map(double).map(cube)
59
+
60
+ assert_equal([], msgs)
61
+ assert_equal(8, eight.run_effects)
62
+ assert_equal(['Starting with nothing'], msgs)
63
+ end
64
+
65
+ def test_use_as_proc
66
+ Kernel.define_method(:eg, &EG)
67
+ o = eg(
68
+ foo: -> { :bar }
69
+ )
70
+ assert_equal(:bar, o.foo)
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eg
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Sharon Rosner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: modulation
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.20'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.20'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 5.11.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 5.11.3
41
+ description:
42
+ email: ciconia@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - README.md
47
+ - CHANGELOG.md
48
+ files:
49
+ - ".gitignore"
50
+ - CHANGELOG.md
51
+ - LICENSE
52
+ - README.md
53
+ - TODO.md
54
+ - eg.gemspec
55
+ - lib/eg.rb
56
+ - lib/eg/version.rb
57
+ - test/test_eg.rb
58
+ homepage: http://github.com/digital-fabric/eg
59
+ licenses:
60
+ - MIT
61
+ metadata:
62
+ source_code_uri: https://github.com/digital-fabric/eg
63
+ post_install_message:
64
+ rdoc_options:
65
+ - "--title"
66
+ - EG
67
+ - "--main"
68
+ - README.md
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.0.3
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: 'EG: Prototype-based objects for Ruby'
86
+ test_files: []