safety 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 82ccd013a24f2ad81da78340b9ceceae95240f52
4
+ data.tar.gz: 9d5429001690a7a33dabcce0002103560bfcff2a
5
+ SHA512:
6
+ metadata.gz: e1c567f91aa9079323da52b092dfa5dfff36e3c656f758c95fc6844cbce4dc6b66d78d1e3c3c8c86885bacc47d2c3518c26def7a23bcc78802f726d393b928d6
7
+ data.tar.gz: 0fa062d38e2f969ea32b374723c4ace3a96dd803b1905b5e0f072b3a7a8683a282caeb1880aa33e5c3c5a78f0e602d8e363ff1e9367344d1a52cba3fd852d3c7
@@ -0,0 +1,13 @@
1
+ module SafetyAttributeHelper
2
+ def self.parse_attribute_type method
3
+ if method.to_s =~ /attr_accessor_[a-zA-Z_]*/
4
+ :accessor
5
+ elsif method.to_s =~ /attr_reader_[a-zA-Z_]*/
6
+ :reader
7
+ elsif method.to_s =~ /attr_writer_[a-zA-Z_]*/
8
+ :writer
9
+ else
10
+ nil
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ require 'safety/safety_attribute_helper'
2
+ module SafetyModule
3
+ def respond_to?(method)
4
+ if SafetyAttributeHelper.parse_attribute_type method
5
+ true
6
+ else
7
+ super
8
+ end
9
+ end
10
+
11
+ def method_missing(method, *args, &block)
12
+ type = SafetyAttributeHelper.parse_attribute_type method
13
+ if type
14
+ # Extract the type name from the attribute declaration
15
+ type_name = method.to_s.slice("attr_#{type.to_s}_".length...method.to_s.length)
16
+
17
+ # If the type name is var, type safety will be disabled for this attribute
18
+ should_enforce_type_safety = type_name != 'var'
19
+
20
+ # The class to enforce type safety on
21
+ type_safe_class = nil
22
+
23
+ # Get the type, which could be deep in modules
24
+ if should_enforce_type_safety == true
25
+ type_safe_class = type_name.split('::').inject(Object.class) do |current_module, class_name|
26
+ current_module.const_get(class_name)
27
+ end
28
+ end
29
+
30
+ # Define enforce safety for this property
31
+ define_method "__enforce_safety_#{args[0]}".to_sym do |value|
32
+ # If enforcing type and value is not of type safe class, raise TypeError
33
+ if should_enforce_type_safety == true and value.is_a?(type_safe_class) == false
34
+ raise TypeError, "Type Safe Attribute \"#{args[0]}\", of type \"#{type_safe_class}\", set to value \"#{value}\" of class \"#{value.class}\"."
35
+ end
36
+ return value
37
+ end
38
+
39
+ # A way to get the default value
40
+ define_method "__default_value_#{args[0]}".to_sym do
41
+ if args[1] != nil
42
+ return args[1]
43
+ else
44
+ return nil
45
+ end
46
+ end
47
+
48
+ # Set default, if one was provided
49
+ #set_value.call(args[1]) if args[1] != nil
50
+ define_method "__lazy_instantiator_#{args[0]}".to_sym do
51
+ return block
52
+ end
53
+
54
+ lazy_instantiation = <<EVAL
55
+ def __lazy_instantiation_#{args[0]}
56
+ return nil if __lazy_instantiator_#{args[0]}().nil?
57
+ instance_exec &__lazy_instantiator_#{args[0]}
58
+ end
59
+ EVAL
60
+
61
+ getter = <<EVAL
62
+ def #{args[0]}
63
+ @#{args[0]} = __lazy_instantiation_#{args[0]} if @#{args[0]}.nil? && __lazy_instantiator_#{args[0]} != nil
64
+ @#{args[0]} = __enforce_safety_#{args[0]}(__default_value_#{args[0]}) if @#{args[0]}.nil? && __default_value_#{args[0]} != nil
65
+ __enforce_safety_#{args[0]}(@#{args[0]})
66
+ end
67
+ EVAL
68
+
69
+ setter = <<EVAL
70
+ def #{args[0]}= value
71
+ @#{args[0]} = __enforce_safety_#{args[0]}(value)
72
+ end
73
+ EVAL
74
+
75
+ to_evaluate = lazy_instantiation
76
+ case type
77
+ when :accessor
78
+ to_evaluate << getter
79
+ to_evaluate << setter
80
+ when :reader
81
+ to_evaluate << getter
82
+ when :writer
83
+ to_evaluate << setter
84
+ end
85
+
86
+ self.class_eval to_evaluate
87
+ else
88
+ super
89
+ end
90
+ end
91
+ end
data/lib/safety.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'safety/safety_module'
2
+ module Safety
3
+ def self.included(base)
4
+ base.extend SafetyModule
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safety
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - James Lawrence Turner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Allows you to create type safe attributes in Ruby. Attributes may also
14
+ have default values or lazy instantiators
15
+ email: james@jameslawrenceturner.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/safety.rb
21
+ - lib/safety/safety_module.rb
22
+ - lib/safety/safety_attribute_helper.rb
23
+ homepage: http://github.com/jlturner/safety
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.1.11
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Type Safety in Ruby
47
+ test_files: []