classprop 1.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 +7 -0
- data/README.md +93 -0
- data/lib/classprop.rb +99 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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. |
|
data/lib/classprop.rb
ADDED
@@ -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: []
|