Skip to content

Commit 1778d27

Browse files
transclaude
andcommitted
Review Kernel methods: deprecate 12 redundant methods
- Deprecate 6 singleton_class synonyms: eigenclass (tribute to _why), extension, instance_class, qua_class, object_class, and update meta_class to delegate to singleton_class internally - Keep meta_class/meta_def/meta_eval/meta_alias as concise alternatives - Deprecate object_send (use public_send), instance_send (use __send__) - Deprecate load_relative (use require_relative) - Deprecate returning (use tap) - Deprecate memo (use Module#memoize; global $MEMO is problematic) - 40 unique methods kept Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a0dba26 commit 1778d27

12 files changed

Lines changed: 65 additions & 158 deletions

HISTORY.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ Changes:
110110
* Deprecate `Module#can` (use `Module#extend`).
111111
* Deprecate `File.null` (use `File::NULL` constant, Ruby 1.9.3+).
112112
* Deprecate `File.read_binary` (use `File.binread`, Ruby 1.9.3+).
113+
* Deprecate `Kernel#eigenclass` (use `singleton_class` or `meta_class`; kept in tribute to _why).
114+
* Deprecate `Kernel#extension`, `#instance_class`, `#qua_class`, `#object_class`
115+
(use `singleton_class` or `meta_class`).
116+
* Deprecate `Kernel#object_send` (use `public_send`), `#instance_send` (use `__send__`).
117+
* Deprecate `Kernel#load_relative` (use `require_relative`).
118+
* Deprecate `Kernel#returning` (use `Kernel#tap`).
119+
* Deprecate `Kernel#memo` (use `Module#memoize`; global `$MEMO` is problematic).
120+
* Update `Kernel#meta_class` to delegate to `singleton_class` internally.
113121
* Fix dead requires for removed `kernel/singleton_class` in Proc and Kernel.
114122
* Remove misplaced `applique/file_helpers` from core (test infrastructure).
115123
* Drop unused `test_files` directive from gemspec. (PR#301)

lib/core/facets/kernel/eigenclass.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@ module Kernel
33
# During this trying time when no one can get their
44
# techie catchwords to stick to the refrigerator no
55
# matter how hard they slap it with the enchanted
6-
# magnetic spatula, its good to know that the
6+
# magnetic spatula, it's good to know that the
77
# contrived phrases really do fly, graceful and
88
# unclasped and bearing north toward chilled shrimp.
9-
# I know what my Halloween pumpkin is going to say.
9+
# I know what my Hallowe'en pumpkin is going to say.
1010
#
11-
# NOTE: This method is not a common core extension and is not
12-
# loaded automatically when using `require 'facets'`.
11+
# @deprecated Use singleton_class or meta_class instead.
12+
# Kept in tribute to WhyTheLuckyStiff who coined the term.
1313
#
1414
# CREDIT: WhyTheLuckyStiff
1515
#
1616
# @uncommon
1717
# require 'facets/kernel/eigenclass'
1818
#
1919
def eigenclass
20-
(class << self; self; end)
20+
warn "Kernel#eigenclass is deprecated. Use singleton_class or meta_class instead.", uplevel: 1
21+
singleton_class
2122
end
2223

2324
end
24-
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
module Kernel
22

3-
# TODO: Must reduce the number of singleton method methods.
4-
5-
# Don't say it!
6-
#
3+
# @deprecated Use singleton_class or meta_class instead.
74
def extension
8-
class << self; self; end
5+
warn "Kernel#extension is deprecated. Use singleton_class or meta_class instead.", uplevel: 1
6+
singleton_class
97
end
108

119
end
12-
Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,10 @@
11
module Kernel
22

3-
# Kernel extension prefixed by instance_ which provide
4-
# internal (eg private) access to the object.
5-
# Kernel extension using instance_ prefix which is beneficial
6-
# to separation of metaprogramming from general programming.
7-
# object_ methods, in contrast to the instance_ methods,
8-
# do not access internal state.
9-
10-
# Easy access to an object qua class, otherwise known
11-
# as the object's metaclass or singleton class. This
12-
# implemnetation alwasy returns the class, even if a
13-
# block is provided to eval against it...
14-
#
15-
# It is what it is.
16-
# But I think I like this one best.
17-
#
18-
# CREDIT: Trans
19-
3+
# @deprecated Use singleton_class or meta_class instead.
204
def instance_class(&block)
21-
(class << self; self; end).module_eval(&block) if block
22-
(class << self; self; end)
5+
warn "Kernel#instance_class is deprecated. Use singleton_class or meta_class instead.", uplevel: 1
6+
singleton_class.module_eval(&block) if block
7+
singleton_class
238
end
249

2510
end
26-

lib/core/facets/kernel/instance_send.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module Kernel
22

3-
# Private send.
4-
alias_method :instance_send, :__send__
3+
# @deprecated Use __send__ instead.
4+
def instance_send(name, *args, &blk)
5+
warn "Kernel#instance_send is deprecated. Use __send__ instead.", uplevel: 1
6+
__send__(name, *args, &blk)
7+
end
58

69
end
7-
Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,13 @@
11
module Kernel
22

3-
unless private_method_defined?(:load_relative) # Will Ruby ever support out-of-the-box?
4-
5-
# Load file from same dir as calling script.
6-
#
7-
# load_relative 'myscript'
8-
#
9-
# CREDIT: Paul Brannan, Pragmatic Programmers
10-
#
11-
def load_relative(relative_feature, safe=nil)
12-
c = caller.first
13-
fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/)
14-
file = $` # File.dirname(c)
15-
if /\A\((.*)\)/ =~ file # eval, etc.
16-
raise LoadError, "require_relative is called in #{$1}"
17-
end
18-
absolute = File.expand_path(relative_feature, File.dirname(file))
19-
load absolute, safe
20-
end
21-
3+
# @deprecated Use require_relative for requires; for load, use
4+
# an absolute path via File.expand_path.
5+
def load_relative(relative_feature, safe=nil)
6+
warn "Kernel#load_relative is deprecated.", uplevel: 1
7+
loc = caller_locations(1, 1).first
8+
file = loc.absolute_path || loc.path
9+
absolute = File.expand_path(relative_feature, File.dirname(file))
10+
load absolute, safe
2211
end
2312

2413
end
25-

lib/core/facets/kernel/memo.rb

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,14 @@
1-
require 'facets/binding/eval'
2-
require 'facets/kernel/__method__'
3-
41
module Kernel
52

6-
# Global memo cache.
7-
$MEMO ||= {}
8-
9-
# Memoize a method.
10-
#
11-
# class MemoExample
12-
# attr_accessor :a
13-
# def m
14-
# memo{ @a }
15-
# end
16-
# end
17-
#
18-
# ex = MemoExample.new
19-
#
20-
# ex.a = 10
21-
# ex.m #=> 10
22-
#
23-
# ex.a = 20
24-
# ex.m #=> 10
25-
#
26-
# NOTE: This method is not a common core extension and is not
27-
# loaded automatically when using <code>require 'facets'</code>.
3+
# @deprecated Use Module#memoize instead, which provides proper
4+
# per-object memoization without a global variable.
285
#
296
# @uncommon
307
# require 'facets/kernel/memo'
318
#
329
def memo(*args, &block)
10+
warn "Kernel#memo is deprecated. Use Module#memoize instead.", uplevel: 1
11+
$MEMO ||= {}
3312
if args.empty?
3413
args = block.binding.eval('[self, __method__]')
3514
end
@@ -41,4 +20,3 @@ def memo(*args, &block)
4120
end
4221

4322
end
44-
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
module Kernel
22

3-
# Easy access to an object's "special" class, otherwise known as it's
4-
# singleton class, eigenclass, adhoc class or object-qua-class.
5-
#
3+
# Easy access to an object's singleton class, with optional block eval.
4+
#
5+
# obj.meta_class #=> #<Class:obj>
6+
# obj.meta_class { def foo; end }
7+
#
8+
# This is a concise alternative to Ruby's `singleton_class` that also
9+
# accepts a block for class_eval.
10+
#
611
def meta_class(&block)
712
if block_given?
8-
(class << self; self; end).class_eval(&block)
13+
singleton_class.class_eval(&block)
914
else
10-
(class << self; self; end)
15+
singleton_class
1116
end
1217
end
1318

14-
# The non-underscored form of #meta_class if faily common.
1519
alias_method :metaclass, :meta_class
1620

1721
end
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
module Kernel
22

3-
# Defines object_classas an alias of class.
4-
# This is an alternative to __class__, akin to
5-
# #object_id.
6-
7-
alias_method :object_class, :class
3+
# @deprecated Use __class__ instead.
4+
def object_class
5+
warn "Kernel#object_class is deprecated. Use __class__ instead.", uplevel: 1
6+
self.class
7+
end
88

99
end
10-
Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,9 @@
11
module Kernel
22

3-
# Send only to public methods.
4-
#
5-
# class SendExample
6-
# private
7-
# def foo; end
8-
# end
9-
#
10-
# obj = SendExample.new
11-
#
12-
# expect NoMethodError do
13-
# obj.object_send(:foo)
14-
# end
15-
#
16-
# DEPRECATED: Use #public_send instead.
17-
18-
alias object_send public_send rescue nil
19-
20-
#def object_send(name, *args, &blk)
21-
# #instance_eval "self.#{name}(*args)"
22-
# if respond_to?(name)
23-
# __send__(name, *args, &blk)
24-
# else
25-
# __send__(:method_missing, name, *args, &blk)
26-
# end
27-
#end
3+
# @deprecated Use public_send instead (built-in since Ruby 1.9.2).
4+
def object_send(name, *args, &blk)
5+
warn "Kernel#object_send is deprecated. Use public_send instead.", uplevel: 1
6+
public_send(name, *args, &blk)
7+
end
288

299
end
30-

0 commit comments

Comments
 (0)