如何逃避 IRB 的范围?
How to escape scope in IRB?
在我的 .irbrc 文件中,我尝试编写某种构造、class、方法、模块,这样当我在 IRB session 中调用构造时,它将输出当前可用 object 的交错数组以及 class 那些 object 的来源。
在活动的 IRB session 中,我使用以下方法成功创建了这个交错数组:
>> class Ticket
>> def event
>> "Stuff"
>> end
>> end
>>
>> ticket1 = Ticket.new
>> => #<Ticket:0x25f5900>
>> ticket2 = Ticket.new
>> => #<Ticket:0x27622c8>
>> ticket3 = Ticket.new
>> => #<Ticket:0x304f590>
>>
>> available_objects_array = ObjectSpace.each_object(Ticket).to_a
>> => [#<Ticket:0x25f5900>, #<Ticket:0x27622c8>, #<Ticket:0x304f590>]
>> local_variables_array = local_variables.delete_if {|y| eval(y.to_s).class != Ticket}
>> => [:ticket3, :ticket2, :ticket1]
>> local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
>> => ["ticket1", "ticket2", "ticket3"]
>> objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
>> => ["ticket1", #<Ticket:0x25f5900>, "ticket2", #<Ticket:0x27622c8>, "ticket3", #<Ticket:0x304f590>]
所以,到目前为止一切都很好。
然后我在我的 .irbrc 文件中创建了一个新方法:
def show_top_locals(class_param)
available_objects_array = ObjectSpace.each_object(class_param).to_a
local_variables_array = local_variables.delete_if {|y| eval(y.to_s).class != class_param}
local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
end
并启动了另一个 IRB session 并手动重新创建了 Ticket
class 和 ticket1
、ticket2
和 ticket3
变量。最后,我尝试使用show_top_locals
方法:
>> show_top_locals(Ticket)
=> []
我什么也没得到,因为我在 local_variables_array
变量中使用的 Kernel.local_variables
方法只查找在 show_top_locals
方法范围内定义的变量。
然后我在一个单独的文件中制作了一个模块并需要该文件并将该模块包含在我的 .irbrc 中:
require '.\testruby.rb'
include Top
这是我的模块:
#testruby.rb
module Top
ShowVars = Class.new do
p Kernel.local_variables
define_method(:toplevelvars) do
p Kernel.local_variables
end
end
end
回到新的 IRB session:
>> show_vars = ShowVars.new
>> => #<Top::ShowVars:0x1eac1e8>
>> show_vars.toplevelvars
[]
=> []
我仍然被困在错误的范围内。
如何在 .irbrc 中编写可在 IRB session 中使用的代码,以提供上述交错 object 和变量数组?
您似乎没有从您的方法 show_top_locals
返回所有值。此外,在方法内调用 Kernel#local_variables
只会从方法范围内查找局部变量。您应该从调用方法的地方传递绑定,以便在调用方法的地方获得局部变量列表。
require "pp"
# For backward compatibility with Ruby 2.1 and below
def local_vars(binding)
if binding.respond_to? :local_variables
binding.local_variables
else
eval "Kernel.local_variables", binding
end
end
def show_top_locals(class_param, binding)
available_objects_array = ObjectSpace.each_object(class_param).to_a
local_variables_array = local_vars(binding).delete_if {|y| binding.eval(y.to_s).class != class_param}
local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
return {
available_objs: available_objects_array,
local_vars: local_variables_array,
local_vars_reversed: local_variables_array_reversed,
objs_and_vars: objects_and_variables_array
}
end
class Foo
end
a = Foo.new
b = Foo.new
pp show_top_locals(Foo, binding)
#=> {:available_objs=>[#<Foo:0x000000027825b0>, #<Foo:0x000000027825d8>],
# :local_vars=>[:a, :b],
# :local_vars_reversed=>["b", "a"],
# :objs_and_vars=>["b", #<Foo:0x000000027825b0>, "a", #<Foo:0x000000027825d8>]}
您可以将方法 show_top_locals
放在 .rb
文件中,并参考“Can you 'require' ruby file in irb session, automatically, on every command?”在 IRB 中自动加载它。
在我的 .irbrc 文件中,我尝试编写某种构造、class、方法、模块,这样当我在 IRB session 中调用构造时,它将输出当前可用 object 的交错数组以及 class 那些 object 的来源。
在活动的 IRB session 中,我使用以下方法成功创建了这个交错数组:
>> class Ticket
>> def event
>> "Stuff"
>> end
>> end
>>
>> ticket1 = Ticket.new
>> => #<Ticket:0x25f5900>
>> ticket2 = Ticket.new
>> => #<Ticket:0x27622c8>
>> ticket3 = Ticket.new
>> => #<Ticket:0x304f590>
>>
>> available_objects_array = ObjectSpace.each_object(Ticket).to_a
>> => [#<Ticket:0x25f5900>, #<Ticket:0x27622c8>, #<Ticket:0x304f590>]
>> local_variables_array = local_variables.delete_if {|y| eval(y.to_s).class != Ticket}
>> => [:ticket3, :ticket2, :ticket1]
>> local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
>> => ["ticket1", "ticket2", "ticket3"]
>> objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
>> => ["ticket1", #<Ticket:0x25f5900>, "ticket2", #<Ticket:0x27622c8>, "ticket3", #<Ticket:0x304f590>]
所以,到目前为止一切都很好。
然后我在我的 .irbrc 文件中创建了一个新方法:
def show_top_locals(class_param)
available_objects_array = ObjectSpace.each_object(class_param).to_a
local_variables_array = local_variables.delete_if {|y| eval(y.to_s).class != class_param}
local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
end
并启动了另一个 IRB session 并手动重新创建了 Ticket
class 和 ticket1
、ticket2
和 ticket3
变量。最后,我尝试使用show_top_locals
方法:
>> show_top_locals(Ticket)
=> []
我什么也没得到,因为我在 local_variables_array
变量中使用的 Kernel.local_variables
方法只查找在 show_top_locals
方法范围内定义的变量。
然后我在一个单独的文件中制作了一个模块并需要该文件并将该模块包含在我的 .irbrc 中:
require '.\testruby.rb'
include Top
这是我的模块:
#testruby.rb
module Top
ShowVars = Class.new do
p Kernel.local_variables
define_method(:toplevelvars) do
p Kernel.local_variables
end
end
end
回到新的 IRB session:
>> show_vars = ShowVars.new
>> => #<Top::ShowVars:0x1eac1e8>
>> show_vars.toplevelvars
[]
=> []
我仍然被困在错误的范围内。
如何在 .irbrc 中编写可在 IRB session 中使用的代码,以提供上述交错 object 和变量数组?
您似乎没有从您的方法 show_top_locals
返回所有值。此外,在方法内调用 Kernel#local_variables
只会从方法范围内查找局部变量。您应该从调用方法的地方传递绑定,以便在调用方法的地方获得局部变量列表。
require "pp"
# For backward compatibility with Ruby 2.1 and below
def local_vars(binding)
if binding.respond_to? :local_variables
binding.local_variables
else
eval "Kernel.local_variables", binding
end
end
def show_top_locals(class_param, binding)
available_objects_array = ObjectSpace.each_object(class_param).to_a
local_variables_array = local_vars(binding).delete_if {|y| binding.eval(y.to_s).class != class_param}
local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
return {
available_objs: available_objects_array,
local_vars: local_variables_array,
local_vars_reversed: local_variables_array_reversed,
objs_and_vars: objects_and_variables_array
}
end
class Foo
end
a = Foo.new
b = Foo.new
pp show_top_locals(Foo, binding)
#=> {:available_objs=>[#<Foo:0x000000027825b0>, #<Foo:0x000000027825d8>],
# :local_vars=>[:a, :b],
# :local_vars_reversed=>["b", "a"],
# :objs_and_vars=>["b", #<Foo:0x000000027825b0>, "a", #<Foo:0x000000027825d8>]}
您可以将方法 show_top_locals
放在 .rb
文件中,并参考“Can you 'require' ruby file in irb session, automatically, on every command?”在 IRB 中自动加载它。