classprop 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +93 -0
  3. data/lib/classprop.rb +99 -0
  4. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 97ebdc34c9de6444609a82b228cc26cef04e7ca4e0c062d6786b2d919c9ed2f3
4
+ data.tar.gz: 30ef0193b6f77837fa86a0444c597eb82976b469a8837bbd4b8d43069a05e6ab
5
+ SHA512:
6
+ metadata.gz: cf4fd42454b349e131394d1c13cf1ef10856106345a07a29e2f0317099990aee672b8bfd1b8d7f6668517c94e6ea536ac5cfd8eeec92964c205a71dbe07c0b0c
7
+ data.tar.gz: 54c19c2c4ba81023250118f75a1f5d6723ccc8910dc832999a993fc38b895f8db7266aca0bcfee8f1cbea0af4d87a1546dd7d2071bbcb471c9db849a04251f05
@@ -0,0 +1,93 @@
1
+ # ClassProp
2
+
3
+ ClassProp allows you to set properties of a class which can be inherited or
4
+ overridden by subclasses. For example, in the following code, the `Base` class
5
+ is created and includes `ClassProp`. Then it defines an inheritable property
6
+ called `fco`. Finally, it sets the value of that property to *base*.
7
+
8
+ ```ruby
9
+ class Base
10
+ include ClassProp
11
+ define_class_prop 'fco'
12
+ @fco = 'base'
13
+ end
14
+ ```
15
+
16
+ The `fco` property is now available from `Base`.
17
+
18
+ ```ruby
19
+ puts Base.fco # => 'base'
20
+ ```
21
+
22
+ Another class can inherit from `Base`.
23
+
24
+ ```ruby
25
+ class X1 < Base
26
+ end
27
+ ```
28
+
29
+ If `X1` does not define its own `fco` property, then when that property is
30
+ retrieved from `X1` it returns `Base.fco`.
31
+
32
+ ```ruby
33
+ puts X1.fco # => 'base'
34
+ ```
35
+
36
+ `X1` can set its own value for `fco`.
37
+
38
+ ```ruby
39
+ class X1
40
+ @fco = 'x1'
41
+ end
42
+ ```
43
+
44
+ That gives us this output.
45
+
46
+ ```ruby
47
+ puts X1.fco # => 'x1'
48
+ ```
49
+
50
+ To delete a class property (so that the property is again inherited from the
51
+ superclass) use `delete_class_prop`.
52
+
53
+ ```ruby
54
+ class X1
55
+ delete_class_prop 'fco'
56
+ end
57
+
58
+ puts X1.fco # => 'base'
59
+ ```
60
+
61
+ You can set a property so that it must be defined by subclasses. To do so, set
62
+ the property to `ClassProp::MustDefine`. If an inheriting class does not define
63
+ that property then an error is raised when the property is retrieved.
64
+
65
+ ```ruby
66
+ class Base
67
+ include ClassProp
68
+ define_class_prop 'fco'
69
+ @fco = ClassProp::MustDefine
70
+ end
71
+
72
+ class X1 < Base
73
+ end
74
+
75
+ X1.fco # raises exception 'must-define-class-class-property: fco'
76
+ ```
77
+
78
+ ## Install
79
+
80
+ ```
81
+ gem install classprop
82
+ ```
83
+
84
+ ## Author
85
+
86
+ Mike O'Sullivan
87
+ mike@idocs.com
88
+
89
+ ## History
90
+
91
+ | version | date | notes |
92
+ |---------|--------------|-------------------------------|
93
+ | 1.0 | Feb 24, 2020 | Initial upload. |
@@ -0,0 +1,99 @@
1
+ #===============================================================================
2
+ # ClassProp
3
+ #
4
+ module ClassProp
5
+ # version 1.0
6
+ VERSION = '1.0'
7
+
8
+ # private
9
+ private
10
+
11
+ # Adds class methods when module is included.
12
+ def self.included(base)
13
+ base.extend ClassMethods
14
+ end
15
+
16
+ #---------------------------------------------------------------------------
17
+ # MustDefine
18
+ #
19
+
20
+ # This module itself does not do anything. If you set a class property to
21
+ # ClassProp::MustDefine then subclasses must define that property. For
22
+ # example, the following code raise an exception.
23
+ #
24
+ # class Base
25
+ # include ClassProp
26
+ # define_class_prop 'fco'
27
+ # self.fco = ClassProp::MustDefine
28
+ # end
29
+ #
30
+ # class X1 < Base
31
+ # end
32
+ #
33
+ # X1.fco # raises exception 'must-define-class-class-property: fco'
34
+ module MustDefine
35
+ end
36
+
37
+ #
38
+ # MustDefine
39
+ #---------------------------------------------------------------------------
40
+
41
+
42
+ #---------------------------------------------------------------------------
43
+ # ClassMethods
44
+ #
45
+ module ClassMethods
46
+ # Normalizes a property name so that any leading @ is removed.
47
+ def normalize(prop_name)
48
+ prop_name = prop_name.to_s
49
+ prop_name = prop_name.sub(/\A\@/mu, '')
50
+ return prop_name
51
+ end
52
+
53
+ # Defines the set and get methods for the given property.
54
+ def define_class_prop(prop_name)
55
+ prop_name = normalize(prop_name)
56
+
57
+ # set
58
+ self.define_singleton_method("#{prop_name}=") do |val|
59
+ instance_variable_set "@#{prop_name}", val
60
+ end
61
+
62
+ # get
63
+ self.define_singleton_method(prop_name) do
64
+ if instance_variable_defined?("@#{prop_name}")
65
+ rv = instance_variable_get("@#{prop_name}")
66
+
67
+ if rv == ClassProp::MustDefine
68
+ raise "must-define-class-class-property: #{prop_name}"
69
+ else
70
+ return rv
71
+ end
72
+ else
73
+ if superclass.respond_to?(prop_name)
74
+ return superclass.public_send(prop_name)
75
+ else
76
+ return nil
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ # delete_class_prop
83
+ def delete_class_prop(prop_name)
84
+ prop_name = normalize(prop_name)
85
+
86
+ if instance_variable_defined?("@#{prop_name}")
87
+ remove_instance_variable "@#{prop_name}"
88
+ end
89
+ end
90
+
91
+
92
+ end
93
+ #
94
+ # ClassMethods
95
+ #---------------------------------------------------------------------------
96
+ end
97
+ #
98
+ # ClassProp
99
+ #===============================================================================
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: classprop
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Mike O'Sullivan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Set attributes of a class that can be inherited and overridden
14
+ email: mike@idocs.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - README.md
20
+ - lib/classprop.rb
21
+ homepage: https://rubygems.org/gems/classprop
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.7.6
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Inheritable class attributes
45
+ test_files: []