abstractivator 0.0.19 → 0.0.20

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: 3e4b42be94b67b4941fa92b59dde30b82f7f5621
4
- data.tar.gz: 60fbb6aef6b5e1d5b238e5b25b93e555f19d0de7
3
+ metadata.gz: e2e72efdd6bc89faf5f8b2cfa863d7fed8dc643e
4
+ data.tar.gz: 4ff37a3fb3cb13a2ef309a954c3220406f219585
5
5
  SHA512:
6
- metadata.gz: 52b1865dd2933ca08c785188be8efa59d284bff6e2e965138b25fcefd42309ce3d6cc16913a059dcc4c4470077631e5be9d01514b1251f96d27c9bdbadef1ee9
7
- data.tar.gz: 4e98f6f9f0e31efb1b1445b0aa6f7a299780b99581679a8019a2a295098b9c5a99792c62c3fecf1d2b9d7865fc3351496f987912f2918855501816f80ff97ca5
6
+ metadata.gz: 5fe33acb32046988112b02e974747349d6fb124e333416cbdacc3bb7797e22cc3ed38559b0470d5d91afca3f91ac60dfbca2980ad92503df0bb82b2b70d0ccee
7
+ data.tar.gz: 89ba9f0d00caf957ca7c3b588d9f8c48abfca63913df185a449eeed55c21bf11c1bec08c59f83a687ccf76c9eb4cd4fb798b39d7c9456cd504744fa201b6c0b6
@@ -1,13 +1,16 @@
1
1
  require 'active_support/inflector'
2
+ require 'abstractivator/enumerable_ext'
3
+ require 'delegate'
2
4
 
3
5
  module Enum
4
6
  def self.included(base)
5
7
  base.extend ClassMethods
8
+ # base.extend Dsl
6
9
  end
7
10
 
8
11
  module ClassMethods
9
12
  def values
10
- self.constants.map{|sym| self.const_get(sym)}
13
+ self.constants.map{|sym| self.const_get(sym)}.reject{|x| x == Enum::ClassMethods}
11
14
  end
12
15
 
13
16
  def name_for(value)
@@ -18,6 +21,8 @@ module Enum
18
21
  safe_constantize("#{self.name}::#{sym.to_s.upcase}")
19
22
  end
20
23
 
24
+ private
25
+
21
26
  def safe_constantize(str)
22
27
  begin
23
28
  str.constantize
@@ -27,3 +32,43 @@ module Enum
27
32
  end
28
33
  end
29
34
  end
35
+
36
+ module EnumMember
37
+ attr_accessor :enum_type
38
+ end
39
+
40
+ class Object
41
+ include EnumMember
42
+ end
43
+
44
+ class WrappedEnumValue < SimpleDelegator
45
+ include EnumMember
46
+ attr_reader :class # pure evil
47
+ def initialize(value)
48
+ __setobj__(value)
49
+ @class = value.class
50
+ end
51
+ end
52
+
53
+ def define_enum(name, *fields)
54
+ const_set(name, make_enum(*fields))
55
+ end
56
+
57
+ def make_enum(*fields)
58
+ if fields.size == 1 && fields.first.is_a?(Hash) && fields.first.keys.all?{|f| f.is_a?(Symbol)}
59
+ fields = fields.first
60
+ Module.new do
61
+ include Enum
62
+ fields.each_pair do |k, v|
63
+ val = v.frozen? ? WrappedEnumValue.new(v) : v
64
+ val.enum_type = self
65
+ fld = k.to_s.upcase.to_sym
66
+ const_set(fld, val)
67
+ end
68
+ end
69
+ elsif fields.all?{|f| f.is_a?(Symbol)}
70
+ make_enum(fields.hash_map(&:to_s))
71
+ else
72
+ raise 'Arguments must be one or more symbols or a single symbol-keyed hash'
73
+ end
74
+ end
@@ -47,7 +47,7 @@ module Enumerable
47
47
  x.respond_to?(:call)
48
48
  end
49
49
 
50
- def hash_map(get_key, &get_value)
50
+ def hash_map(get_key=->x{x}, &get_value)
51
51
  Hash[self.map{|x| [get_key.(x), get_value ? get_value.(x) : x]}]
52
52
  end
53
53
 
@@ -91,4 +91,14 @@ module Enumerable
91
91
  block ||= proc { value }
92
92
  self + ([n-self.size, 0].max).times.map(&block)
93
93
  end
94
+
95
+ def stable_sort(&compare)
96
+ compare = compare || ->(a, b){a <=> b}
97
+ xis = self.each_with_index.map{|x, i| [x, i]}
98
+ sorted = xis.sort do |(a, ai), (b, bi)|
99
+ primary = compare.call(a, b)
100
+ primary != 0 ? primary : (ai <=> bi)
101
+ end
102
+ sorted.map(&:first)
103
+ end
94
104
  end
@@ -1,3 +1,3 @@
1
1
  module Abstractivator
2
- VERSION = '0.0.19'
2
+ VERSION = '0.0.20'
3
3
  end
@@ -1,11 +1,2 @@
1
- module Enumerable
2
- def stable_sort(&compare)
3
- compare = compare || ->(a, b){a <=> b}
4
- xis = self.each_with_index.map{|x, i| [x, i]}
5
- sorted = xis.sort do |(a, ai), (b, bi)|
6
- primary = compare.call(a, b)
7
- primary != 0 ? primary : (ai <=> bi)
8
- end
9
- sorted.map(&:first)
10
- end
11
- end
1
+ # deprecate this file
2
+ require 'abstractivator/enumerable_ext'
@@ -0,0 +1,58 @@
1
+ require 'rspec'
2
+ require 'abstractivator/enum'
3
+
4
+ class Container
5
+ module Traditional
6
+ include Enum
7
+ FOO = 'foo'
8
+ BAR = 'bar'
9
+ end
10
+
11
+ define_enum(:Fruits, :apple, :orange)
12
+ define_enum(:Vegetables, cucumber: 'Cucumis sativus', eggplant: 8)
13
+ end
14
+
15
+ describe Enum do
16
+ describe '::values' do
17
+ it 'enumerates the values' do
18
+ expect(Container::Traditional.values).to eql %w(foo bar)
19
+ end
20
+ end
21
+ describe '::name_for' do
22
+ it 'returns the symbol name of an enum value' do
23
+ expect(Container::Traditional.name_for('foo')).to eql :FOO
24
+ end
25
+ it 'return nil if the value does not belong to the enumeration' do
26
+ expect(Container::Traditional.name_for('baz')).to be_nil
27
+ end
28
+ end
29
+ describe '::from_symbol' do
30
+ it 'coerces a symbol to an enum value' do
31
+ expect(Container::Traditional.from_symbol(:bar)).to eql 'bar'
32
+ end
33
+ it 'raises an error if no such value exists in the enumeration' do
34
+ expect{Container::Traditional.from_symbol(:baz)}.to raise_error
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '#define_enum' do
40
+ it 'defines an enum given an array of symbols' do
41
+ expect(Container::Fruits::APPLE).to eql 'apple'
42
+ expect(Container::Fruits::ORANGE).to eql 'orange'
43
+ end
44
+ it 'defines an enum given a hash' do
45
+ expect(Container::Vegetables::CUCUMBER).to eql 'Cucumis sativus'
46
+ expect(Container::Vegetables::EGGPLANT).to eql 8
47
+ end
48
+ it 'values know their parent' do
49
+ expect(Container::Fruits::APPLE.enum_type).to eql Container::Fruits
50
+ expect(Container::Fruits::ORANGE.enum_type).to eql Container::Fruits
51
+ expect(Container::Vegetables::CUCUMBER.enum_type).to eql Container::Vegetables
52
+ expect(Container::Vegetables::EGGPLANT.enum_type).to eql Container::Vegetables
53
+ end
54
+ it 'raises an error when called with bad arguments' do
55
+ expect{define_enum(:Stuff, 5)}.to raise_error /Arguments must be/
56
+ expect{define_enum(:Stuff, '!@$' => '')}.to raise_error /Arguments must be/
57
+ end
58
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abstractivator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Winton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-05 00:00:00.000000000 Z
11
+ date: 2015-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,7 @@ files:
94
94
  - spec/lib/abstractivator/array_ext_spec.rb
95
95
  - spec/lib/abstractivator/collections_spec.rb
96
96
  - spec/lib/abstractivator/cons_spec.rb
97
+ - spec/lib/abstractivator/enum_spec.rb
97
98
  - spec/lib/abstractivator/enumerable_ext_spec.rb
98
99
  - spec/lib/abstractivator/proc_ext_spec.rb
99
100
  - spec/lib/abstractivator/tree_visitor_spec.rb
@@ -126,6 +127,7 @@ test_files:
126
127
  - spec/lib/abstractivator/array_ext_spec.rb
127
128
  - spec/lib/abstractivator/collections_spec.rb
128
129
  - spec/lib/abstractivator/cons_spec.rb
130
+ - spec/lib/abstractivator/enum_spec.rb
129
131
  - spec/lib/abstractivator/enumerable_ext_spec.rb
130
132
  - spec/lib/abstractivator/proc_ext_spec.rb
131
133
  - spec/lib/abstractivator/tree_visitor_spec.rb