루비의 현재 범위에 현재 사용 가능한 객체를 어떻게 나열합니까?
-
04-07-2019 - |
문제
나는 루비를 처음 사용하고 IRB와 함께 놀고 있습니다.
나는 ".methods"메소드를 사용하여 객체의 메소드를 나열 할 수 있음을 발견했습니다.내장)?)하지만 포함 및 요구를 통해로드 한 라이브러리/모듈의 방법을 어떻게 찾을 수 있습니까?
irb(main):036:0* self.methods
=> ["irb_pop_binding", "inspect", "taguri", "irb_chws", "clone", "irb_pushws", "public_methods", "taguri=", "irb_pwws",
"public", "display", "irb_require", "irb_exit", "instance_variable_defined?", "irb_cb", "equal?", "freeze", "irb_context
", "irb_pop_workspace", "irb_cwb", "irb_jobs", "irb_bindings", "methods", "irb_current_working_workspace", "respond_to?"
, "irb_popb", "irb_cws", "fg", "pushws", "conf", "dup", "cwws", "instance_variables", "source", "cb", "kill", "help", "_
_id__", "method", "eql?", "irb_pwb", "id", "bindings", "send", "singleton_methods", "popb", "irb_kill", "chws", "taint",
"irb_push_binding", "instance_variable_get", "frozen?", "irb_source", "pwws", "private", "instance_of?", "__send__", "i
rb_workspaces", "to_a", "irb_quit", "to_yaml_style", "irb_popws", "irb_change_workspace", "jobs", "type", "install_alias
_method", "irb_push_workspace", "require_gem", "object_id", "instance_eval", "protected_methods", "irb_print_working_wor
kspace", "irb_load", "require", "==", "cws", "===", "irb_pushb", "instance_variable_set", "irb_current_working_binding",
"extend", "kind_of?", "context", "gem", "to_yaml_properties", "quit", "popws", "irb", "to_s", "to_yaml", "irb_fg", "cla
ss", "hash", "private_methods", "=~", "tainted?", "include", "irb_cwws", "irb_change_binding", "irb_help", "untaint", "n
il?", "pushb", "exit", "irb_print_working_binding", "is_a?", "workspaces"]
irb(main):037:0>
나는 Python에 익숙하며 Dir () 함수를 사용하여 같은 것을 달성합니다.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>>
해결책
ObjectSpace.each_object 당신이 찾고있는 것일 수 있습니다.
사용할 수있는 포함 된 모듈 목록을 얻으려면 module.included_modules.
객체가 케이스 별으로 메소드에 응답하는지 확인할 수도 있습니다. object.respent_to?.
다른 팁
나는 당신이 '현재 객체'가 의미하는 바를 완전히 확신하지 못합니다. 이미 언급 된대로 ObjectSpace를 반복 할 수 있습니다. 그러나 다음은 몇 가지 다른 방법이 있습니다.
local_variables
instance_variables
global_variables
class_variables
constants
Gotcha가 있습니다. 올바른 범위에서 호출해야합니다. 따라서 IRB 또는 객체 인스턴스 또는 클래스 범위 (기본적으로 어디서나)에서 첫 번째 3을 호출 할 수 있습니다.
local_variables #=> ["_"]
foo = "bar"
local_variables #=> ["_", "foo"]
# Note: the _ variable in IRB contains the last value evaluated
_ #=> "bar"
instance_variables #=> []
@inst_var = 42
instance_variables #=> ["@inst_var"]
global_variables #=> ["$-d", "$\"", "$$", "$<", "$_", ...]
$" #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]
그러나 음, 프로그램을 많이 입력하지 않고도 프로그램을 평가할 필요가 있다면 어떨까요? 트릭은 평가입니다.
eval "@inst_var" #=> 42
global_variables.each do |v|
puts eval(v)
end
처음에 언급 된 5 중 마지막 2 개는 모듈 수준에서 평가되어야합니다 (클래스는 모듈의 후손이므로 작동합니다).
Object.class_variables #=> []
Object.constants #=> ["IO", "Duration", "UNIXserver", "Binding", ...]
class MyClass
A_CONST = 'pshh'
class InnerClass
end
def initialize
@@meh = "class_var"
end
end
MyClass.constants #=> ["A_CONST", "InnerClass"]
MyClass.class_variables #=> []
mc = MyClass.new
MyClass.class_variables #=> ["@@meh"]
MyClass.class_eval "@@meh" #=> "class_var"
다음은 다른 방향으로 탐색 할 몇 가지 트릭입니다.
"".class #=> String
"".class.ancestors #=> [String, Enumerable, Comparable, ...]
String.ancestors #=> [String, Enumerable, Comparable, ...]
def trace
return caller
end
trace #=> ["(irb):67:in `irb_binding'", "/System/Library/Frameworks/Ruby...", ...]
그만큼 dir()
방법은 명확하게 정의되지 않았습니다...
메모: 왜냐하면
dir()
대화식 프롬프트에서 사용하기위한 편리함으로 주로 제공되며, 엄격하거나 일관되게 정의 된 이름 세트를 제공하려고하는 것보다 흥미로운 이름 세트를 제공하려고 시도하며, 상세한 행동은 릴리스에서 변경 될 수 있습니다.
...하지만 우리는 루비에서 근사한 근사치를 만들 수 있습니다. 포함 된 모듈별로 우리의 범위에 추가 된 모든 메소드 목록을 반환하는 메소드를 만들어 봅시다. 사용하여 포함 된 모듈 목록을 얻을 수 있습니다. included_modules
방법.
처럼 dir()
, 우리는 "기본"메소드를 무시하고 싶습니다 ( print
), 우리는 또한 "흥미로운"이름 세트에 집중하고 싶습니다. 따라서 우리는 방법을 무시할 것입니다 Kernel
, 우리는 상속 된 방법을 무시하고 모듈에서 직접 정의 된 메소드 만 반환합니다. 우리는 나중에 통과하여 달성 할 수 있습니다 false
로 methods()
방법. 모든 것을 합쳐서 우리는 얻는다 ...
def included_methods(object=self)
object = object.class if object.class != Class
modules = (object.included_modules-[Kernel])
modules.collect{ |mod| mod.methods(false)}.flatten.sort
end
클래스, 객체 또는 아무것도 전달할 수 있습니다 (현재 범위로 기본값). 해보자 ...
irb(main):006:0> included_methods
=> []
irb(main):007:0> include Math
=> Object
irb(main):008:0> included_methods
=> ["acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "cos", "cosh", "erf", "erfc", "exp", "frexp", "hypot", "ldexp", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"]
dir()
또한 로컬로 정의 된 변수가 포함되어 있으며 이는 쉬운 변수입니다. 그냥 전화 ...
local_variables
... 불행히도, 우리는 단지 추가 할 수 없습니다 local_variables
~에게 전화 해 included_methods
그것은 우리에게 로컬에있는 변수를 제공하기 때문에 included_methods
방법은 그다지 유용하지 않습니다. 따라서 포함 된 로컬 변수가 포함되어 있으면 conlude_methods에 전화하십시오.
(included_methods + local_variables).sort
나는 그것을 위해 보석을 썼다 :
$ gem install method_info
$ rvm use 1.8.7 # (1.8.6 works but can be very slow for an object with a lot of methods)
$ irb
> require 'method_info'
> 5.method_info
::: Fixnum :::
%, &, *, **, +, -, -@, /, <, <<, <=, <=>, ==, >, >=, >>, [], ^, abs,
div, divmod, even?, fdiv, id2name, modulo, odd?, power!, quo, rdiv,
rpower, size, to_f, to_s, to_sym, zero?, |, ~
::: Integer :::
ceil, chr, denominator, downto, floor, gcd, gcdlcm, integer?, lcm,
next, numerator, ord, pred, round, succ, taguri, taguri=, times, to_i,
to_int, to_r, to_yaml, truncate, upto
::: Precision :::
prec, prec_f, prec_i
::: Numeric :::
+@, coerce, eql?, nonzero?, pretty_print, pretty_print_cycle,
remainder, singleton_method_added, step
::: Comparable :::
between?
::: Object :::
clone, to_yaml_properties, to_yaml_style, what?
::: MethodInfo::ObjectMethod :::
method_info
::: Kernel :::
===, =~, __clone__, __id__, __send__, class, display, dup, enum_for,
equal?, extend, freeze, frozen?, hash, id, inspect, instance_eval,
instance_exec, instance_of?, instance_variable_defined?,
instance_variable_get, instance_variable_set, instance_variables,
is_a?, kind_of?, method, methods, nil?, object_id, pretty_inspect,
private_methods, protected_methods, public_methods, respond_to?, ri,
send, singleton_methods, taint, tainted?, tap, to_a, to_enum, type,
untaint
=> nil
전달 옵션 및 설정 기본값을 개선하려고하지만 지금은 .irbrc 파일에 다음을 추가하는 것이 좋습니다.
require 'method_info'
MethodInfo::OptionHandler.default_options = {
:ancestors_to_exclude => [Object],
:enable_colors => true
}
이렇게하면 색상을 가능하게하고 모든 객체에 관심이 없기 때문에 모든 객체가 가지고있는 방법을 숨 깁니다.
는 어때:
Object.constants.select{|x| eval(x.to_s).class == Class}
그것은 나를 위해 사용 가능한 수업을 나열합니다. 나는 루비 전문가가 아니며 어떤 수업이 있는지 전혀 모른 채 루비 콘솔에 떨어졌습니다. 그 하나의 라이너는 시작이었습니다.
Ruby의 모든 객체 인스턴스에 액세스하려면 ObjectSpace를 사용합니다.
http://www.ruby-doc.org/core-1.8.7/classes/objectspace.html#m000928
그러나 이것은 느리게 간주되며 (루비의 경우) 일부 통역사에서는 활성화되지 않을 수 있습니다 (예 : Jruby는 Jruby 에서이 물건을 추적 할 필요없이 JVM에 대한 JVM에서 훨씬 빠르게 의존하기 때문에 Objectspace를 비활성화 할 수 있습니다).
.methods 메시지를로드하기 전에도 라이브러리/모듈에 전달하여 사용 가능한 모든 방법을 볼 수 있습니다. 행위 self.methods
객체 객체에 포함 된 모든 메소드를 반환합니다. 당신은 그렇게함으로써 이것을 볼 수 있습니다 self.class
. 파일 모듈의 모든 메소드를보고 싶다고 가정 해 봅시다. 당신은 단순히합니다 File.methods
또한 파일 모듈에 존재하는 모든 메소드의 목록을 얻을 수 있습니다. 이것은 아마도 당신이 원하는 것이 아니지만 다소 도움이되어야합니다.