Pergunta

Eu sou novo para Ruby e eu estou brincando com o IRB.

Eu descobri que eu posso listar os métodos de um objeto usando o ".methods" método e que self.methods tipo de dá-me o que eu quero (semelhante ao dir do Python ( builtins )?) , mas como posso encontrar os métodos de uma biblioteca / módulo I já carregado via incluem e exigem?

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>

Estou acostumado a python, onde eu uso a função dir () para realizar a mesma coisa:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>>
Foi útil?

Solução

ObjectSpace.each_object poderia ser o que que você está procurando.

Para obter uma lista de módulos incluídos você pode usar Module.included_modules .

Você também pode verificar se um objeto responde a um método em uma base caso a caso, utilizando object.respond_to? .

Outras dicas

Eu não estou totalmente certo do que você quer dizer com os 'objetos atuais'. Você pode iterar sobre ObjectSpace, como já foi mencionado. Mas aqui estão alguns outros métodos.

local_variables
instance_variables
global_variables

class_variables
constants

Há uma pegadinha. Eles devem ser chamados nos âmbitos certas. Portanto, mesmo no IRB, ou em uma instância de objeto ou pelo escopo de classe (para todos os lugares, basicamente) você pode chamar o primeiro 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", ...]

Mas umm, e se você quer que seu programa realmente avaliá-los sem a necessidade que você os digite manyally? O truque é eval.

eval "@inst_var" #=> 42
global_variables.each do |v|
  puts eval(v)
end

A última 2 do 5 mencionado no início deve ser avaliada no nível de módulo (a classe é um descendente de um módulo, de modo que as obras).

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"

Estão aqui estão mais alguns truques para explorar em direções diferentes

"".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...", ...]

O método dir() é href="http://www.python.org/doc/2.5.2/lib/built-in-funcs.html" não está claramente definido ...

Nota: Porque dir() é fornecido principalmente como uma conveniência para uso em um prompt interativo, ele tenta fornecer um interessante conjunto de nomes mais do que tenta fornecer uma conjunto ou rigorosamente definidas de maneira consistente de nomes, e seu comportamento detalhado pode mudar entre os releases.

... mas podemos criar uma aproximação em Ruby. Vamos fazer um método que irá retornar uma lista ordenada de todos os métodos adicionados ao nosso alcance por módulos incluídos. Podemos obter uma lista dos módulos que foram incluídos usando o método included_modules.

Como dir(), queremos ignorar os métodos "padrão" (como print), e também quer se concentrar no jogo "interessante" de nomes. Então, vamos ignorar métodos em Kernel, e só vamos métodos que foram definidos diretamente nos módulos, ignorando métodos herdados voltar. Podemos realizar o mais tarde, passando false no método methods(). Juntando tudo chegamos ...

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

Você pode passá-lo uma classe, um objeto, ou nada (o padrão é o escopo atual). Vamos testá-lo ...

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() também inclui variáveis ??definidas localmente, e isso é fácil. chamada simplesmente ...

local_variables

... infelizmente, não podemos simplesmente adicionar a chamada local_variables para included_methods porque nos daria as variáveis ??que são locais para o método included_methods, e isso não seria muito útil. Então, se você quiser variáveis ??locais incluídos com os included_methods, basta ligar ...

 (included_methods + local_variables).sort

Eu escrevi uma jóia para isso:

$ 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

Eu estou trabalhando em uma melhoria de passar opções e configurações padrões, mas por agora eu sugiro que você adicione o seguinte ao seu arquivo .irbrc:

require 'method_info'
MethodInfo::OptionHandler.default_options = {
 :ancestors_to_exclude => [Object],
 :enable_colors => true
}

Isso permite que as cores e esconde os métodos que cada objeto tem, desde que você normalmente não está interessado em pessoas.

E:

Object.constants.select{|x| eval(x.to_s).class == Class}

As classes que listas disponíveis para mim. Eu não sou rubi perito e eu estava sendo deixado cair em um console ruby ??sem idéia do que aulas eram à mão. Que um forro era um começo.

Para acessar todas as instâncias de objetos em Ruby você usa ObjectSpace

http: //www.ruby-doc .org / core-1.8.7 / aulas / ObjectSpace.html # M000928

No entanto, isso é considerado lento (mesmo para Ruby), e não pode ser ativado em alguns intérpretes (por exemplo jRuby pode desativar ObjectSpace como ele é muito mais rápido confiando na JVM para gc sem a necessidade de acompanhar este material em jRuby).

Você pode passar as mensagens .methods para a biblioteca / módulo mesmo antes de carregá-lo, para ver todos os métodos disponíveis. Fazendo self.methods apenas retorna todos os métodos que o objeto objeto contém. Você pode ver isso fazendo self.class. Então, digamos que você quer ver todos os métodos no módulo de arquivo. Você simplesmente fazer File.methods e você terá uma lista de todos os métodos existentes no módulo de arquivo. Este, talvez, não é o que você quer, mas deve ser um pouco útil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top