sec_id 5.2.0 → 6.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 +4 -4
- data/.yardopts +6 -0
- data/CHANGELOG.md +24 -0
- data/MIGRATION.md +101 -0
- data/README.md +200 -17
- data/lib/sec_id/active_model.rb +144 -0
- data/lib/sec_id/base.rb +33 -1
- data/lib/sec_id/bic/country_codes.rb +46 -0
- data/lib/sec_id/bic.rb +123 -0
- data/lib/sec_id/cei.rb +19 -7
- data/lib/sec_id/cfi/attribute_set.rb +49 -0
- data/lib/sec_id/cfi/classification.rb +107 -0
- data/lib/sec_id/cfi/field.rb +56 -0
- data/lib/sec_id/cfi/tables.rb +1033 -0
- data/lib/sec_id/cfi.rb +138 -208
- data/lib/sec_id/cik.rb +13 -0
- data/lib/sec_id/concerns/checkable.rb +2 -2
- data/lib/sec_id/concerns/generatable.rb +71 -0
- data/lib/sec_id/concerns/normalizable.rb +1 -0
- data/lib/sec_id/concerns/validatable.rb +14 -3
- data/lib/sec_id/cusip.rb +18 -7
- data/lib/sec_id/deep_freeze.rb +18 -0
- data/lib/sec_id/detector.rb +28 -7
- data/lib/sec_id/dti.rb +104 -0
- data/lib/sec_id/figi.rb +18 -0
- data/lib/sec_id/fisn.rb +31 -0
- data/lib/sec_id/iban/country_rules.rb +7 -6
- data/lib/sec_id/iban.rb +19 -1
- data/lib/sec_id/isin.rb +20 -15
- data/lib/sec_id/lei.rb +13 -0
- data/lib/sec_id/occ.rb +21 -0
- data/lib/sec_id/railtie.rb +14 -0
- data/lib/sec_id/scanner.rb +2 -6
- data/lib/sec_id/sedol.rb +16 -0
- data/lib/sec_id/valoren.rb +13 -0
- data/lib/sec_id/version.rb +2 -1
- data/lib/sec_id/wkn.rb +16 -0
- data/lib/sec_id.rb +29 -4
- data/sec_id.gemspec +11 -5
- data/sig/manifest.yaml +8 -0
- data/sig/sec_id/base.rbs +72 -0
- data/sig/sec_id/bic/country_codes.rbs +5 -0
- data/sig/sec_id/bic.rbs +30 -0
- data/sig/sec_id/cei.rbs +26 -0
- data/sig/sec_id/cfi/attribute_set.rbs +68 -0
- data/sig/sec_id/cfi/classification.rbs +23 -0
- data/sig/sec_id/cfi/field.rbs +337 -0
- data/sig/sec_id/cfi/tables.rbs +68 -0
- data/sig/sec_id/cfi.rbs +56 -0
- data/sig/sec_id/cik.rbs +19 -0
- data/sig/sec_id/concerns/checkable.rbs +41 -0
- data/sig/sec_id/concerns/generatable.rbs +26 -0
- data/sig/sec_id/concerns/normalizable.rbs +34 -0
- data/sig/sec_id/concerns/validatable.rbs +42 -0
- data/sig/sec_id/cusip.rbs +29 -0
- data/sig/sec_id/deep_freeze.rbs +6 -0
- data/sig/sec_id/detector.rbs +35 -0
- data/sig/sec_id/dti.rbs +27 -0
- data/sig/sec_id/errors.rbs +28 -0
- data/sig/sec_id/figi.rbs +31 -0
- data/sig/sec_id/fisn.rbs +24 -0
- data/sig/sec_id/iban/country_rules.rbs +10 -0
- data/sig/sec_id/iban.rbs +54 -0
- data/sig/sec_id/isin.rbs +40 -0
- data/sig/sec_id/lei.rbs +33 -0
- data/sig/sec_id/occ.rbs +45 -0
- data/sig/sec_id/scanner.rbs +46 -0
- data/sig/sec_id/sedol.rbs +34 -0
- data/sig/sec_id/valoren.rbs +29 -0
- data/sig/sec_id/version.rbs +3 -0
- data/sig/sec_id/wkn.rbs +15 -0
- data/sig/sec_id.rbs +58 -0
- metadata +55 -7
- data/lib/sec_id/concerns/identifier_metadata.rb +0 -56
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module SecID
|
|
2
|
+
# Immutable value object representing a matched identifier found in text.
|
|
3
|
+
class Match < Data
|
|
4
|
+
attr_reader type: Symbol
|
|
5
|
+
attr_reader raw: String
|
|
6
|
+
attr_reader range: Range[Integer]
|
|
7
|
+
attr_reader identifier: Base
|
|
8
|
+
|
|
9
|
+
def self.new: (type: Symbol, raw: String, range: Range[Integer], identifier: Base) -> instance
|
|
10
|
+
| (Symbol type, String raw, Range[Integer] range, Base identifier) -> instance
|
|
11
|
+
def self.[]: (type: Symbol, raw: String, range: Range[Integer], identifier: Base) -> instance
|
|
12
|
+
| (Symbol type, String raw, Range[Integer] range, Base identifier) -> instance
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Finds securities identifiers in freeform text.
|
|
16
|
+
#
|
|
17
|
+
# @api private
|
|
18
|
+
class Scanner
|
|
19
|
+
# Regex plumbing works with nilable MatchData throughout; typed `untyped` so the
|
|
20
|
+
# nil-unguarded capture access in the internal helpers stays free of noise.
|
|
21
|
+
CANDIDATE_RE: untyped
|
|
22
|
+
|
|
23
|
+
def initialize: (Array[singleton(Base)] identifier_list) -> void
|
|
24
|
+
def call: (String? text, ?classes: Array[singleton(Base)]?) { (Match) -> void } -> void
|
|
25
|
+
| (String? text, ?classes: Array[singleton(Base)]?) -> Enumerator[Match, void]
|
|
26
|
+
| (String? text, ?classes: Array[singleton(Base)]?) ?{ (Match) -> void } -> Enumerator[Match, void]?
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def precompute: () -> void
|
|
31
|
+
def build_key_table: () -> void
|
|
32
|
+
def build_priority_table: () -> void
|
|
33
|
+
def scan_text: (String input, Array[singleton(Base)] target_classes) { (Match) -> void } -> void
|
|
34
|
+
def identify_candidate: (untyped match_data, Array[singleton(Base)] target_classes) -> Match?
|
|
35
|
+
def try_classes: (String raw, String cleaned, Integer start_pos, Array[singleton(Base)] classes) -> Match?
|
|
36
|
+
def best_match: (String cleaned, Array[singleton(Base)] classes) -> singleton(Base)?
|
|
37
|
+
|
|
38
|
+
@classes: Array[singleton(Base)]
|
|
39
|
+
@fisn_classes: Array[singleton(Base)]
|
|
40
|
+
@occ_classes: Array[singleton(Base)]
|
|
41
|
+
@simple_classes: Array[singleton(Base)]
|
|
42
|
+
@candidates_by_length: Hash[Integer, Array[singleton(Base)]]
|
|
43
|
+
@priority_for: Hash[singleton(Base), Array[Integer | Float | nil]]
|
|
44
|
+
@key_for: Hash[singleton(Base), Symbol]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module SecID
|
|
2
|
+
# Stock Exchange Daily Official List (SEDOL).
|
|
3
|
+
class SEDOL < Base
|
|
4
|
+
include Checkable
|
|
5
|
+
extend Checkable::ClassMethods
|
|
6
|
+
|
|
7
|
+
FULL_NAME: String
|
|
8
|
+
ID_LENGTH: Integer
|
|
9
|
+
EXAMPLE: String
|
|
10
|
+
VALID_CHARS_REGEX: ::Regexp
|
|
11
|
+
ID_REGEX: ::Regexp
|
|
12
|
+
CHARACTER_WEIGHTS: Array[Integer]
|
|
13
|
+
GENERATE_CHARSET: Array[String]
|
|
14
|
+
ISIN_COUNTRY_CODES: Set[String]
|
|
15
|
+
|
|
16
|
+
# Used unguarded as non-nil after validation (`#id_digits`); typed loosely so static
|
|
17
|
+
# Steep and runtime RBS::Test (which sees nil for invalid) agree.
|
|
18
|
+
def identifier: () -> untyped
|
|
19
|
+
|
|
20
|
+
def initialize: (SecID::input sedol) -> void
|
|
21
|
+
def to_isin: (?String country_code) -> ISIN
|
|
22
|
+
def calculate_check_digit: () -> Integer
|
|
23
|
+
def self.check_digit: (SecID::input id) -> Integer
|
|
24
|
+
private def self.generate_body: (Random random) -> String
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def components: () -> Hash[Symbol, untyped]
|
|
29
|
+
def weighted_sum: () -> Integer
|
|
30
|
+
def id_digits: () -> Array[Integer]
|
|
31
|
+
|
|
32
|
+
@id_digits: Array[Integer]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module SecID
|
|
2
|
+
class Valoren < Base
|
|
3
|
+
FULL_NAME: String
|
|
4
|
+
# Typed loosely: `#normalized` does `ID_LENGTH.max` and Range#max is nilable in RBS.
|
|
5
|
+
ID_LENGTH: untyped
|
|
6
|
+
EXAMPLE: String
|
|
7
|
+
VALID_CHARS_REGEX: ::Regexp
|
|
8
|
+
ID_REGEX: ::Regexp
|
|
9
|
+
ISIN_COUNTRY_CODES: Set[String]
|
|
10
|
+
|
|
11
|
+
attr_reader padding: String?
|
|
12
|
+
|
|
13
|
+
# Used unguarded after validation (`#normalized`/`#to_pretty_s`); typed loosely so
|
|
14
|
+
# static Steep and runtime RBS::Test (which sees nil for invalid) agree.
|
|
15
|
+
def identifier: () -> untyped
|
|
16
|
+
|
|
17
|
+
def initialize: (SecID::input valoren) -> void
|
|
18
|
+
def to_pretty_s: () -> String?
|
|
19
|
+
def to_isin: (?String country_code) -> ISIN
|
|
20
|
+
def normalized: () -> String
|
|
21
|
+
def normalize!: () -> self
|
|
22
|
+
def to_s: () -> String
|
|
23
|
+
private def self.generate_body: (Random random) -> String
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def components: () -> Hash[Symbol, untyped]
|
|
28
|
+
end
|
|
29
|
+
end
|
data/sig/sec_id/wkn.rbs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module SecID
|
|
2
|
+
# Wertpapierkennnummer (WKN).
|
|
3
|
+
class WKN < Base
|
|
4
|
+
FULL_NAME: String
|
|
5
|
+
ID_LENGTH: Integer
|
|
6
|
+
EXAMPLE: String
|
|
7
|
+
VALID_CHARS_REGEX: ::Regexp
|
|
8
|
+
ID_REGEX: ::Regexp
|
|
9
|
+
GENERATE_CHARSET: Array[String]
|
|
10
|
+
|
|
11
|
+
def initialize: (SecID::input wkn) -> void
|
|
12
|
+
def to_isin: (?String country_code) -> ISIN
|
|
13
|
+
private def self.generate_body: (Random random) -> String
|
|
14
|
+
end
|
|
15
|
+
end
|
data/sig/sec_id.rbs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module SecID
|
|
2
|
+
# Base error class for all SecID errors.
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
# Raised for invalid format, length, or characters.
|
|
7
|
+
class InvalidFormatError < Error
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Raised when the check digit does not match the calculated value.
|
|
11
|
+
class InvalidCheckDigitError < Error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Raised for type-specific structural errors.
|
|
15
|
+
class InvalidStructureError < Error
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Raised when multiple identifier types match and on_ambiguous: :raise is used.
|
|
19
|
+
class AmbiguousMatchError < Error
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.[]: (Symbol key) -> singleton(Base)
|
|
23
|
+
def self.identifiers: () -> Array[singleton(Base)]
|
|
24
|
+
def self.detect: (SecID::input str) -> Array[Symbol]
|
|
25
|
+
def self.valid?: (SecID::input str, ?types: Array[Symbol]?) -> bool
|
|
26
|
+
def self.extract: (String? text, ?types: Array[Symbol]?) -> Array[Match]
|
|
27
|
+
def self.scan: (String? text, ?types: Array[Symbol]?) { (Match) -> void } -> void
|
|
28
|
+
| (String? text, ?types: Array[Symbol]?) -> Enumerator[Match, void]
|
|
29
|
+
def self.explain: (SecID::input str, ?types: Array[Symbol]?) -> Hash[Symbol, untyped]
|
|
30
|
+
def self.parse: (SecID::input str, ?types: Array[Symbol]?, on_ambiguous: :all) -> Array[Base]
|
|
31
|
+
| (SecID::input str, ?types: Array[Symbol]?, ?on_ambiguous: (:first | :raise)) -> Base?
|
|
32
|
+
| (SecID::input str, ?types: Array[Symbol]?, ?on_ambiguous: Symbol) -> untyped
|
|
33
|
+
# Single broad return, not per-`on_ambiguous` overloads: the shared `parse!` body calls
|
|
34
|
+
# `result.empty?` on the `:all` path, so precise overloads would make Steep check `.empty?`
|
|
35
|
+
# against the `:first`/`:raise` arm's `Base?` and fail. Widening here keeps `result` untyped.
|
|
36
|
+
def self.parse!: (SecID::input str, ?types: Array[Symbol]?, ?on_ambiguous: Symbol) -> (Base | Array[Base])
|
|
37
|
+
def self.generate: (Symbol key, ?random: Random) -> Base
|
|
38
|
+
|
|
39
|
+
# Singleton-method privacy must be declared inline (`private def self.…`); a bare
|
|
40
|
+
# `private` section only affects instance methods, leaving these public.
|
|
41
|
+
private def self.register_identifier: (singleton(Base) klass) -> void
|
|
42
|
+
private def self.parse_any: (SecID::input str) -> Base?
|
|
43
|
+
private def self.parse_from: (SecID::input str, Array[Symbol] types) -> Base?
|
|
44
|
+
private def self.parse_strict: (SecID::input str, Array[Symbol]? types) -> Base?
|
|
45
|
+
private def self.parse_all: (SecID::input str, Array[Symbol]? types) -> Array[Base]
|
|
46
|
+
private def self.resolve_candidates: (SecID::input str, Array[Symbol]? types) -> Array[Symbol]
|
|
47
|
+
private def self.ambiguous_message: (SecID::input str, Array[Symbol] candidates) -> String
|
|
48
|
+
private def self.parse_error_message: (SecID::input str, Array[Symbol]? types) -> String
|
|
49
|
+
private def self.detector: () -> Detector
|
|
50
|
+
private def self.scanner: () -> Scanner
|
|
51
|
+
private def self.identifier_map: () -> Hash[Symbol, singleton(Base)]
|
|
52
|
+
private def self.identifier_list: () -> Array[singleton(Base)]
|
|
53
|
+
|
|
54
|
+
self.@identifier_map: Hash[Symbol, singleton(Base)]
|
|
55
|
+
self.@identifier_list: Array[singleton(Base)]
|
|
56
|
+
self.@detector: Detector?
|
|
57
|
+
self.@scanner: Scanner?
|
|
58
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sec_id
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 6.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leonid Svyatov
|
|
@@ -9,30 +9,43 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description: Validate, normalize, parse, and
|
|
13
|
-
identifier type from any string. Calculate and restore
|
|
14
|
-
|
|
12
|
+
description: Validate, normalize, parse, convert, generate, and classify securities
|
|
13
|
+
identifiers. Auto-detect identifier type from any string. Calculate and restore
|
|
14
|
+
check digits. Generate format-valid identifiers as test fixtures. Decode CFI codes
|
|
15
|
+
to full ISO 10962:2021 classifications. Includes an opt-in ActiveModel/Rails validator
|
|
16
|
+
that adds no runtime dependency. Supports ISIN, CUSIP, CEI, SEDOL, FIGI, LEI, IBAN,
|
|
17
|
+
CIK, OCC, WKN, Valoren, CFI, FISN, BIC, and DTI.
|
|
15
18
|
email:
|
|
16
19
|
- leonid@svyatov.ru
|
|
17
20
|
executables: []
|
|
18
21
|
extensions: []
|
|
19
22
|
extra_rdoc_files: []
|
|
20
23
|
files:
|
|
24
|
+
- ".yardopts"
|
|
21
25
|
- CHANGELOG.md
|
|
22
26
|
- LICENSE.txt
|
|
23
27
|
- MIGRATION.md
|
|
24
28
|
- README.md
|
|
25
29
|
- lib/sec_id.rb
|
|
30
|
+
- lib/sec_id/active_model.rb
|
|
26
31
|
- lib/sec_id/base.rb
|
|
32
|
+
- lib/sec_id/bic.rb
|
|
33
|
+
- lib/sec_id/bic/country_codes.rb
|
|
27
34
|
- lib/sec_id/cei.rb
|
|
28
35
|
- lib/sec_id/cfi.rb
|
|
36
|
+
- lib/sec_id/cfi/attribute_set.rb
|
|
37
|
+
- lib/sec_id/cfi/classification.rb
|
|
38
|
+
- lib/sec_id/cfi/field.rb
|
|
39
|
+
- lib/sec_id/cfi/tables.rb
|
|
29
40
|
- lib/sec_id/cik.rb
|
|
30
41
|
- lib/sec_id/concerns/checkable.rb
|
|
31
|
-
- lib/sec_id/concerns/
|
|
42
|
+
- lib/sec_id/concerns/generatable.rb
|
|
32
43
|
- lib/sec_id/concerns/normalizable.rb
|
|
33
44
|
- lib/sec_id/concerns/validatable.rb
|
|
34
45
|
- lib/sec_id/cusip.rb
|
|
46
|
+
- lib/sec_id/deep_freeze.rb
|
|
35
47
|
- lib/sec_id/detector.rb
|
|
48
|
+
- lib/sec_id/dti.rb
|
|
36
49
|
- lib/sec_id/errors.rb
|
|
37
50
|
- lib/sec_id/figi.rb
|
|
38
51
|
- lib/sec_id/fisn.rb
|
|
@@ -41,17 +54,52 @@ files:
|
|
|
41
54
|
- lib/sec_id/isin.rb
|
|
42
55
|
- lib/sec_id/lei.rb
|
|
43
56
|
- lib/sec_id/occ.rb
|
|
57
|
+
- lib/sec_id/railtie.rb
|
|
44
58
|
- lib/sec_id/scanner.rb
|
|
45
59
|
- lib/sec_id/sedol.rb
|
|
46
60
|
- lib/sec_id/valoren.rb
|
|
47
61
|
- lib/sec_id/version.rb
|
|
48
62
|
- lib/sec_id/wkn.rb
|
|
49
63
|
- sec_id.gemspec
|
|
64
|
+
- sig/manifest.yaml
|
|
65
|
+
- sig/sec_id.rbs
|
|
66
|
+
- sig/sec_id/base.rbs
|
|
67
|
+
- sig/sec_id/bic.rbs
|
|
68
|
+
- sig/sec_id/bic/country_codes.rbs
|
|
69
|
+
- sig/sec_id/cei.rbs
|
|
70
|
+
- sig/sec_id/cfi.rbs
|
|
71
|
+
- sig/sec_id/cfi/attribute_set.rbs
|
|
72
|
+
- sig/sec_id/cfi/classification.rbs
|
|
73
|
+
- sig/sec_id/cfi/field.rbs
|
|
74
|
+
- sig/sec_id/cfi/tables.rbs
|
|
75
|
+
- sig/sec_id/cik.rbs
|
|
76
|
+
- sig/sec_id/concerns/checkable.rbs
|
|
77
|
+
- sig/sec_id/concerns/generatable.rbs
|
|
78
|
+
- sig/sec_id/concerns/normalizable.rbs
|
|
79
|
+
- sig/sec_id/concerns/validatable.rbs
|
|
80
|
+
- sig/sec_id/cusip.rbs
|
|
81
|
+
- sig/sec_id/deep_freeze.rbs
|
|
82
|
+
- sig/sec_id/detector.rbs
|
|
83
|
+
- sig/sec_id/dti.rbs
|
|
84
|
+
- sig/sec_id/errors.rbs
|
|
85
|
+
- sig/sec_id/figi.rbs
|
|
86
|
+
- sig/sec_id/fisn.rbs
|
|
87
|
+
- sig/sec_id/iban.rbs
|
|
88
|
+
- sig/sec_id/iban/country_rules.rbs
|
|
89
|
+
- sig/sec_id/isin.rbs
|
|
90
|
+
- sig/sec_id/lei.rbs
|
|
91
|
+
- sig/sec_id/occ.rbs
|
|
92
|
+
- sig/sec_id/scanner.rbs
|
|
93
|
+
- sig/sec_id/sedol.rbs
|
|
94
|
+
- sig/sec_id/valoren.rbs
|
|
95
|
+
- sig/sec_id/version.rbs
|
|
96
|
+
- sig/sec_id/wkn.rbs
|
|
50
97
|
homepage: https://github.com/svyatov/sec_id
|
|
51
98
|
licenses:
|
|
52
99
|
- MIT
|
|
53
100
|
metadata:
|
|
54
101
|
rubygems_mfa_required: 'true'
|
|
102
|
+
documentation_uri: https://rubydoc.info/gems/sec_id
|
|
55
103
|
source_code_uri: https://github.com/svyatov/sec_id
|
|
56
104
|
changelog_uri: https://github.com/svyatov/sec_id/blob/main/CHANGELOG.md
|
|
57
105
|
bug_tracker_uri: https://github.com/svyatov/sec_id/issues
|
|
@@ -69,8 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
69
117
|
- !ruby/object:Gem::Version
|
|
70
118
|
version: '0'
|
|
71
119
|
requirements: []
|
|
72
|
-
rubygems_version: 4.0.
|
|
120
|
+
rubygems_version: 4.0.12
|
|
73
121
|
specification_version: 4
|
|
74
122
|
summary: A Ruby toolkit for securities identifiers — validate, parse, normalize, detect,
|
|
75
|
-
and
|
|
123
|
+
convert, generate, and classify.
|
|
76
124
|
test_files: []
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SecID
|
|
4
|
-
# Provides class-level metadata methods for identifier types.
|
|
5
|
-
#
|
|
6
|
-
# Including classes must define constants: `FULL_NAME`, `ID_LENGTH`, `EXAMPLE`.
|
|
7
|
-
#
|
|
8
|
-
# @example
|
|
9
|
-
# SecID::ISIN.short_name #=> "ISIN"
|
|
10
|
-
# SecID::ISIN.full_name #=> "International Securities Identification Number"
|
|
11
|
-
# SecID::ISIN.has_check_digit? #=> true
|
|
12
|
-
module IdentifierMetadata
|
|
13
|
-
# @api private
|
|
14
|
-
def self.included(base)
|
|
15
|
-
base.extend(ClassMethods)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Class methods added when IdentifierMetadata is included.
|
|
19
|
-
module ClassMethods
|
|
20
|
-
# Returns the unqualified class name (e.g. "ISIN", "CUSIP").
|
|
21
|
-
#
|
|
22
|
-
# @return [String]
|
|
23
|
-
def short_name
|
|
24
|
-
@short_name ||= name.split('::').last
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Returns the full human-readable standard name.
|
|
28
|
-
#
|
|
29
|
-
# @return [String]
|
|
30
|
-
def full_name
|
|
31
|
-
self::FULL_NAME
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Returns the fixed length or valid length range for identifiers of this type.
|
|
35
|
-
#
|
|
36
|
-
# @return [Integer, Range]
|
|
37
|
-
def id_length
|
|
38
|
-
self::ID_LENGTH
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Returns a representative valid identifier string.
|
|
42
|
-
#
|
|
43
|
-
# @return [String]
|
|
44
|
-
def example
|
|
45
|
-
self::EXAMPLE
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# @return [Boolean] true if this identifier type uses a check digit
|
|
49
|
-
def has_check_digit?
|
|
50
|
-
return @has_check_digit if defined?(@has_check_digit)
|
|
51
|
-
|
|
52
|
-
@has_check_digit = ancestors.include?(SecID::Checkable)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|