루비의 현재 범위에 현재 사용 가능한 객체를 어떻게 나열합니까?

StackOverflow https://stackoverflow.com/questions/228648

  •  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, 우리는 상속 된 방법을 무시하고 모듈에서 직접 정의 된 메소드 만 반환합니다. 우리는 나중에 통과하여 달성 할 수 있습니다 falsemethods() 방법. 모든 것을 합쳐서 우리는 얻는다 ...

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 또한 파일 모듈에 존재하는 모든 메소드의 목록을 얻을 수 있습니다. 이것은 아마도 당신이 원하는 것이 아니지만 다소 도움이되어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top