Skip to content

Commit

Permalink
Store method objects in constants
Browse files Browse the repository at this point in the history
It probably won't speed up things significantly, but these are hot paths
and we can save a few method calls per completion/input call.
  • Loading branch information
st0012 committed Nov 20, 2024
1 parent 9750fa2 commit 5bf7e6a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
18 changes: 12 additions & 6 deletions lib/irb/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,33 @@ def doc_namespace(preposing, matched, _postposing, bind:)
end

class RegexpCompletor < BaseCompletor # :nodoc:
KERNEL_METHODS = ::Kernel.instance_method(:methods)
KERNEL_PRIVATE_METHODS = ::Kernel.instance_method(:private_methods)
KERNEL_INSTANCE_VARIABLES = ::Kernel.instance_method(:instance_variables)
OBJECT_CLASS_INSTANCE_METHOD = ::Object.instance_method(:class)
MODULE_CONSTANTS_INSTANCE_METHOD = ::Module.instance_method(:constants)

using Module.new {
refine ::Binding do
def eval_methods
::Kernel.instance_method(:methods).bind(eval("self")).call
KERNEL_METHODS.bind_call(receiver)
end

def eval_private_methods
::Kernel.instance_method(:private_methods).bind(eval("self")).call
KERNEL_PRIVATE_METHODS.bind_call(receiver)
end

def eval_instance_variables
::Kernel.instance_method(:instance_variables).bind(eval("self")).call
KERNEL_INSTANCE_VARIABLES.bind_call(receiver)
end

def eval_global_variables
::Kernel.instance_method(:global_variables).bind(eval("self")).call
::Kernel.global_variables
end

def eval_class_constants
klass = ::Object.instance_method(:class).bind_call(receiver)
::Module.instance_method(:constants).bind_call(klass)
klass = OBJECT_CLASS_INSTANCE_METHOD.bind_call(receiver)
MODULE_CONSTANTS_INSTANCE_METHOD.bind_call(klass)
end
end
}
Expand Down
7 changes: 5 additions & 2 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ module IRB
# A class that wraps the current state of the irb session, including the
# configuration of IRB.conf.
class Context
KERNEL_PUBLIC_METHOD = ::Kernel.instance_method(:public_method)
KERNEL_METHOD = ::Kernel.instance_method(:method)

ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
# Creates a new IRB context.
#
Expand Down Expand Up @@ -648,8 +651,8 @@ def parse_command(code)
return if local_variables.include?(command)

# Check visibility
public_method = !!Kernel.instance_method(:public_method).bind_call(main, command) rescue false
private_method = !public_method && !!Kernel.instance_method(:method).bind_call(main, command) rescue false
public_method = !!KERNEL_PUBLIC_METHOD.bind_call(main, command) rescue false
private_method = !public_method && !!KERNEL_METHOD.bind_call(main, command) rescue false
if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
[command, arg]
end
Expand Down

0 comments on commit 5bf7e6a

Please sign in to comment.