magic-lookup 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 165ed4c613f3808aa064d20eecc5137a20b74ffca108e4b4edaab39e1de5c710
4
- data.tar.gz: 8c57c00e753425063568765d62f4879a3848de727431663b4199c1e2cc119cd2
3
+ metadata.gz: 6c703f8d45523eb9fe156018f415b24d1eef923ae8abe72b549a8f66944b3d02
4
+ data.tar.gz: 7f473974c2a805aa8bfe766fb1fb0a58692098338a99f09dffbde0b2a6617899
5
5
  SHA512:
6
- metadata.gz: a42291c47d5e2c2d4545f0c7cbb842c03c39ae4f683b177c339832864c1a33fc98b1cc2deadb15e16e87b069cf557fce80e5f8b70ee6bb479921b658704ae208
7
- data.tar.gz: 04b6aaf11baa0644333869e36a0045503b996f13bb1854cc8670d2510220865310e8f01a8b406b56d424328dde9e0690d3d5d5b81cf58cd9c59079fa9eda56fa
6
+ metadata.gz: 68be2c2fb418fe82891c30e8fbc5e8a8b84bcdc3eed3eee8b696ce2cbbf8f538f92b950af599fd3710d977f15c8c0f8f9816784e55454b0995e333b8fa9d63cc
7
+ data.tar.gz: b00b16af1e3aedc9a5c900ef9144f3e669fae21d862b0d856819dfb7eac90320597c496a2ff56f1e117f265cb58ec9b337c1c173cc985868e47b87a812b6f433
data/.rubocop.yml CHANGED
@@ -1,5 +1,7 @@
1
- inherit_from: https://github.com/Alexander-Senko/Alexander-Senko/raw/refs/heads/main/.rubocop.yml
1
+ inherit_from:
2
+ - https://github.com/Alexander-Senko/Alexander-Senko/raw/refs/heads/main/.rubocop.yml
3
+ - https://github.com/Alexander-Senko/Alexander-Senko/raw/refs/heads/main/.rubocop-rspec.yml
2
4
 
3
- require:
5
+ plugins:
4
6
  - rubocop-rspec
5
7
  - rubocop-rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
- ## [Unreleased]
1
+ ## [0.3.0] — 2025-05-20
2
2
 
3
- ## [0.1.0] - 2024-10-07
3
+ ### Added
4
4
 
5
- - Initial release
5
+ - `Magic::Lookup#for` to consider `self` a part of a lookup scope.
6
+
7
+
8
+ ## [0.2.0] — 2024-10-19
9
+
10
+ ### Added
11
+
12
+ - Optional `namespace` parameter to `Magic::Lookup#for` for class lookups within a namespace.
13
+ - `Magic::Lookup#namespaces` to set default lookup namespaces.
14
+
15
+
16
+ ## [0.1.0] — 2024-10-10
17
+
18
+ ### Added
19
+
20
+ - `Magic::Lookup#for` for name-based class lookups.
21
+ - `Magic::Lookup::Error` to be used when lookup fails.
22
+ - `Magic::Lookup::Error.for` factory helper.
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ ![GitHub Actions Workflow Status](
2
+ https://img.shields.io/github/actions/workflow/status/Alexander-Senko/magic-lookup/ci.yml
3
+ )
1
4
  ![Code Climate maintainability](
2
5
  https://img.shields.io/codeclimate/maintainability-percentage/Alexander-Senko/magic-lookup
3
6
  )
@@ -17,21 +20,19 @@ Moreover, inconsistencies across these implementations lead to misunderstanding
17
20
 
18
21
  So, meet
19
22
 
20
- # 🔮Magic Lookup
23
+ # 🔮 Magic Lookup
21
24
 
22
- It's meant to be The One to Rule Them All — the library to provide a generic name-based lookup for a plenty of cases.
25
+ Its meant to be _The One to Rule Them All_ — the library to provide a generic name-based lookup for a plenty of cases.
23
26
 
24
27
  ## Installation
25
28
 
26
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
27
-
28
29
  Install the gem and add to the application's Gemfile by executing:
29
30
 
30
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
31
+ $ bundle add magic-lookup
31
32
 
32
33
  If bundler is not being used to manage dependencies, install the gem by executing:
33
34
 
34
- $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
35
+ $ gem install magic-lookup
35
36
 
36
37
  ## Usage
37
38
 
@@ -68,9 +69,10 @@ scope_class = Scope.for(object.class) or
68
69
  raise Magic::Lookup::Error.for(object, Scope)
69
70
  ```
70
71
 
71
- `Magic::Lookup::Error` is never raised internally and is meant to be used in your code that implements the lookup logic.
72
+ > [!NOTE]
73
+ > `Magic::Lookup::Error` is never raised internally and is meant to be used in your code that implements the lookup logic.
72
74
 
73
- ## Features
75
+ ## 🔮 Magic
74
76
 
75
77
  ### Inheritance
76
78
 
@@ -80,11 +82,33 @@ Lookup is provided not only for the class itself, but to any of its ancestors as
80
82
 
81
83
  Both of matching classes — the target and its match — may be namespaced independently.
82
84
 
85
+ One can specify a namespace to look in:
86
+
87
+ ```ruby
88
+ Scope.for MyModel # => MyScope
89
+ Scope.for MyModel, MyNamespace # => MyNamespace::MyScope
90
+ ```
91
+
92
+ Multiple default lookup namespaces may be set for the base class:
93
+
94
+ ```ruby
95
+ Scope.namespaces << MyNamespace # => [nil, MyNamespace]
96
+ Scope.for MyModel # => MyNamespace::MyScope
97
+ ```
98
+
83
99
  > [!TIP]
84
100
  > Until a comprehensive documentation on all the use cases is released, the spec is recommended as further reading.
85
101
  > One can access it by running `rake` in the gem directory.
86
102
  > The output is quite descriptive to get familiar with the use cases.
87
103
 
104
+ ## Known issues
105
+
106
+ ### https://github.com/Alexander-Senko/magic-lookup/issues/1
107
+
108
+ > [!IMPORTANT]
109
+ > Magic Lookup doesn’t try to autoload any classes, it searches among already loaded ones instead.
110
+ > Thus, one should preload all classes that need to be accessible via the lookup.
111
+
88
112
  ## Development
89
113
 
90
114
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -9,8 +9,8 @@ Gem::Author ||= Struct.new(
9
9
  end
10
10
 
11
11
  module Magic
12
- module Lookup
13
- AUTHORS = [
12
+ module Lookup # :nodoc:
13
+ AUTHORS = [ # rubocop:disable Style/MutableConstant
14
14
  Gem::Author.new(
15
15
  name: 'Alexander Senko',
16
16
  email: 'Alexander.Senko@gmail.com',
@@ -2,6 +2,17 @@
2
2
 
3
3
  module Magic
4
4
  module Lookup
5
+ # = Magic Lookup Error
6
+ #
7
+ # When no class is found, `nil` is returned. If you need to raise
8
+ # an exception in this case, you can use `Magic::Lookup::Error`
9
+ # like this:
10
+ #
11
+ # scope_class = Scope.for(object.class) or
12
+ # raise Magic::Lookup::Error.for(object, Scope)
13
+ #
14
+ # `Magic::Lookup::Error` is never raised internally and is meant
15
+ # to be used by a class implementing the lookup logic.
5
16
  class Error < NameError
6
17
  def self.for object, lookup_class
7
18
  default_name = lookup_class.name_for object.class
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magic
4
+ module Lookup
5
+ module Namespaces # :nodoc:
6
+ attr_writer :namespaces
7
+
8
+ def namespaces = @namespaces ||= [ nil ]
9
+
10
+ def for object_class, *namespaces
11
+ return super unless namespaces.empty?
12
+
13
+ self.namespaces
14
+ .reverse # recently added first
15
+ .lazy # optimization
16
+ .filter_map { super object_class, _1 }
17
+ .first
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Magic
4
4
  module Lookup
5
- VERSION = '0.1.0'
5
+ VERSION = '0.3.0'
6
6
  end
7
7
  end
data/lib/magic/lookup.rb CHANGED
@@ -5,25 +5,56 @@ require_relative 'lookup/version'
5
5
  require 'memery'
6
6
 
7
7
  module Magic
8
+ # = Magic Lookup
9
+ #
10
+ # These are the steps to set up an automatic class inference:
11
+ #
12
+ # 1. Define a base class extending `Magic::Lookup`.
13
+ # 2. Define `.name_for` method for that class implementing your
14
+ # lookup logic.
15
+ # 3. From the base class, inherit classes to be looked up.
16
+ #
17
+ # Example:
18
+ #
19
+ # class Scope
20
+ # extend Magic::Lookup
21
+ #
22
+ # def self.name_for object_class
23
+ # object_class.name
24
+ # .delete_suffix('Model')
25
+ # .concat('Scope')
26
+ # end
27
+ # end
28
+ #
29
+ # class MyScope < Scope
30
+ # end
31
+ #
32
+ # Scope.for MyModel # => MyScope
33
+ # Scope.for OtherModel # => nil
8
34
  module Lookup
9
- autoload :Error, 'magic/lookup/error'
35
+ autoload :Error, 'magic/lookup/error'
36
+ autoload :Namespaces, 'magic/lookup/namespaces'
10
37
 
11
38
  include Memery
12
39
 
13
- memoize def for object_class
40
+ memoize def for object_class, namespace = nil
14
41
  descendants = self.descendants # cache
42
+ .union([ self ]) # including self
15
43
  .reverse # most specific first
16
44
 
17
45
  object_class.ancestors
18
46
  .lazy # optimization
19
47
  .filter(&:name)
20
48
  .map { name_for _1 }
49
+ .map { [ *namespace, _1 ] * '::' }
21
50
  .filter_map do |class_name|
22
51
  descendants.find { _1.name == class_name }
23
52
  end
24
53
  .first
25
54
  end
26
55
 
56
+ prepend Namespaces
57
+
27
58
  def name_for(object_class) = raise NotImplementedError
28
59
 
29
60
  def descendants
data/sig/magic/lookup.rbs CHANGED
@@ -3,7 +3,7 @@ module Magic
3
3
  VERSION: String
4
4
  AUTHORS: Array[Gem::Author]
5
5
 
6
- def for: (Class) -> Class?
6
+ def for: (Class, ?(Module | interned) namespace) -> Class?
7
7
 
8
8
  def name_for: (Module) -> String
9
9
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic-lookup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Senko
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-10-10 00:00:00.000000000 Z
10
+ date: 2025-05-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: memery
@@ -41,6 +41,7 @@ files:
41
41
  - lib/magic/lookup.rb
42
42
  - lib/magic/lookup/authors.rb
43
43
  - lib/magic/lookup/error.rb
44
+ - lib/magic/lookup/namespaces.rb
44
45
  - lib/magic/lookup/version.rb
45
46
  - sig/gem.rbs
46
47
  - sig/magic/lookup.rbs
@@ -51,7 +52,7 @@ licenses:
51
52
  metadata:
52
53
  homepage_uri: https://github.com/Alexander-Senko/magic-lookup
53
54
  source_code_uri: https://github.com/Alexander-Senko/magic-lookup
54
- changelog_uri: https://github.com/Alexander-Senko/magic-lookup/blob/v0.1.0/CHANGELOG.md
55
+ changelog_uri: https://github.com/Alexander-Senko/magic-lookup/blob/v0.3.0/CHANGELOG.md
55
56
  rdoc_options: []
56
57
  require_paths:
57
58
  - lib
@@ -66,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
67
  - !ruby/object:Gem::Version
67
68
  version: '0'
68
69
  requirements: []
69
- rubygems_version: 3.6.0.dev
70
+ rubygems_version: 3.6.5
70
71
  specification_version: 4
71
72
  summary: Related class inference with some magic involved
72
73
  test_files: []