Поиск…


Просмотр методов объекта

Проверка объекта

Вы можете найти общедоступные методы, на которые объект может ответить, используя methods или методы public_methods , которые возвращают массив символов:

class Foo
  def bar; 42; end
end
f = Foo.new
def f.yay; 17; end
p f.methods.sort
#=> [:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :bar, :class, :clone,
#=>  :define_singleton_method, :display, :dup, :enum_for, :eql?, :equal?, :extend,
#=>  :freeze, :frozen?, :hash, :inspect, :instance_eval, :instance_exec,
#=>  :instance_of?, :instance_variable_defined?, :instance_variable_get,
#=>  :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, 
#=>  :method, :methods, :nil?, :object_id, :private_methods, :protected_methods,
#=>  :public_method, :public_methods, :public_send, :remove_instance_variable,
#=>  :respond_to?, :send, :singleton_class, :singleton_method, :singleton_methods,
#=>  :taint, :tainted?, :tap, :to_enum, :to_s, :trust, :untaint, :untrust,
#=>  :untrusted?, :yay]

Для более целевого списка вы можете удалить методы, общие для всех объектов, например

p (f.methods - Object.methods).sort
#=> [:bar,:yay]

Кроме того, вы можете передать false methods или public_methods :

p f.methods(false) # public and protected singleton methods of `f`
#=> [:yay]

p f.public_methods(false)
#=> [:yay, :bar]

Вы можете найти частные и защищенные методы объекта с использованием private_methods и protected_methods :

p f.private_methods.sort
#=> [:Array, :Complex, :DelegateClass, :Float, :Hash, :Integer, :Rational, :String,
#=>  :__callee__, :__dir__, :__method__, :`, :abort, :at_exit, :autoload, :autoload?,
#=>  :binding, :block_given?, :caller, :caller_locations, :catch,
#=>  :default_src_encoding, :eval, :exec, :exit, :exit!, :fail, :fork, :format, :gem,
#=>  :gem_original_require, :gets, :global_variables, :initialize, :initialize_clone,
#=>  :initialize_copy, :initialize_dup, :irb_binding, :iterator?, :lambda, :load,
#=>  :local_variables, :loop, :method_missing, :open, :p, :print, :printf, :proc,
#=>  :putc, :puts, :raise, :rand, :readline, :readlines, :require, :require_relative,
#=>  :respond_to_missing?, :select, :set_trace_func, :singleton_method_added,
#=>  :singleton_method_removed, :singleton_method_undefined, :sleep, :spawn,
#=>  :sprintf, :srand, :syscall, :system, :test, :throw, :trace_var, :trap,
#=>  :untrace_var, :warn]

p f.protected_methods
#=> []

Как и methods и public_methods , вы можете передать false в private_methods и protected_methods чтобы обрезать унаследованные методы.

Проверка класса или модуля

В дополнение к methods public_methods , protected_methods и private_methods , классы и модули выставляют instance_methods , public_instance_methods , protected_instance_methods и private_instance_methods для определения методов, открытых для объектов, которые наследуются от класса или модуля. Как и выше, вы можете передать false этим методам, чтобы исключить унаследованные методы:

p Foo.instance_methods.sort
#=> [:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :bar, :class,
#=>  :clone, :define_singleton_method, :display, :dup, :enum_for, :eql?,
#=>  :equal?, :extend, :freeze, :frozen?, :hash, :inspect, :instance_eval,
#=>  :instance_exec, :instance_of?, :instance_variable_defined?,
#=>  :instance_variable_get, :instance_variable_set, :instance_variables,
#=>  :is_a?, :itself, :kind_of?, :method, :methods, :nil?, :object_id,
#=>  :private_methods, :protected_methods, :public_method, :public_methods,
#=>  :public_send, :remove_instance_variable, :respond_to?, :send,
#=>  :singleton_class, :singleton_method, :singleton_methods, :taint,
#=>  :tainted?, :tap, :to_enum, :to_s, :trust, :untaint, :untrust, :untrusted?]

p Foo.instance_methods(false)
#=> [:bar]

Наконец, если вы забудете имена большинства из них в будущем, вы можете найти все эти методы, используя methods :

p f.methods.grep(/methods/)
#=> [:private_methods, :methods, :protected_methods, :public_methods,
#=>  :singleton_methods]

p Foo.methods.grep(/methods/)
#=> [:public_instance_methods, :instance_methods, :private_instance_methods,
#=>  :protected_instance_methods, :private_methods, :methods,
#=>  :protected_methods, :public_methods, :singleton_methods]

Просмотр переменных экземпляра объекта

Можно запросить объект о его переменных instance_variables , используя instance_variables , instance_variable_defined? , и instance_variable_get , и измените их, используя instance_variable_set и remove_instance_variable :

class Foo
  attr_reader :bar
  def initialize
    @bar = 42
  end
end
f = Foo.new
f.instance_variables                #=> [:@bar]
f.instance_variable_defined?(:@baz) #=> false
f.instance_variable_defined?(:@bar) #=> true
f.instance_variable_get(:@bar)      #=> 42
f.instance_variable_set(:@bar, 17)   #=> 17
f.bar                               #=> 17
f.remove_instance_variable(:@bar)   #=> 17
f.bar                               #=> nil
f.instance_variables                #=> []

Имена переменных экземпляра включают символ @ . Вы получите сообщение об ошибке:

f.instance_variable_defined?(:jim)
#=> NameError: `jim' is not allowed as an instance variable name

Просмотр глобальных и локальных переменных

Kernel предоставляет методы для получения списка global_variables и local_variables :

cats  = 42
$demo = "in progress"
p global_variables.sort
#=> [:$!, :$", :$$, :$&, :$', :$*, :$+, :$,, :$-0, :$-F, :$-I, :$-K, :$-W, :$-a,
#=>  :$-d, :$-i, :$-l, :$-p, :$-v, :$-w, :$., :$/, :$0, :$1, :$2, :$3, :$4, :$5,
#=>  :$6, :$7, :$8, :$9, :$:, :$;, :$<, :$=, :$>, :$?, :$@, :$DEBUG, :$FILENAME,
#=>  :$KCODE, :$LOADED_FEATURES, :$LOAD_PATH, :$PROGRAM_NAME, :$SAFE, :$VERBOSE,
#=>  :$\, :$_, :$`, :$binding, :$demo, :$stderr, :$stdin, :$stdout, :$~]

p local_variables
#=> [:cats]

В отличие от переменных экземпляра нет методов специально для получения, настройки или удаления глобальных или локальных переменных. Поиск такой функциональности обычно является признаком того, что ваш код должен быть переписан, чтобы использовать хэш для хранения значений. Однако, если вы должны изменить глобальные или локальные переменные по имени, вы можете использовать eval со строкой:

var = "$demo"
eval(var)           #=> "in progress"
eval("#{var} = 17")
p $demo             #=> 17

По умолчанию eval будет оценивать ваши переменные в текущей области. Чтобы оценить локальные переменные в другой области, вы должны зафиксировать привязку, где существуют локальные переменные.

def local_variable_get(name, bound=nil)
  foo = :inside
  eval(name,bound)
end

def test_1
  foo = :outside
  p local_variable_get("foo")
end

def test_2
  foo = :outside
  p local_variable_get("foo",binding)
end
  
test_1 #=> :inside
test_2 #=> :outside

В приведенном выше test_1 не передал привязку к local_variable_get , и поэтому eval был выполнен в контексте этого метода, где локальная переменная с именем foo была установлена :inside .

Просмотр переменных класса

Классы и модули имеют одинаковые методы для интроспекции переменных экземпляра как любого другого объекта. Класс и модули также имеют похожие методы для запроса переменных класса ( @@these_things ):

p Module.methods.grep(/class_variable/)
#=> [:class_variables, :class_variable_get, :remove_class_variable,
#=>  :class_variable_defined?, :class_variable_set]

class Foo
  @@instances = 0
  def initialize
    @@instances += 1
  end
end

class Bar < Foo; end

5.times{ Foo.new }
3.times{ Bar.new }
p Foo.class_variables                   #=> [:@@instances]
p Bar.class_variables                   #=> [:@@instances]
p Foo.class_variable_get(:@@instances)  #=> 8
p Bar.class_variable_get(:@@instances)  #=> 8

Подобно переменным экземпляра, имя переменных класса должно начинаться с @@ , или вы получите сообщение об ошибке:

p Bar.class_variable_defined?( :instances )
#=> NameError: `instances' is not allowed as a class variable name


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow