Ruby Language
Introspekcja
Szukaj…
Zobacz metody obiektu
Sprawdzanie obiektu
Możesz znaleźć metody publiczne, na które obiekt może odpowiedzieć, używając methods
lub metod public_methods
, które zwracają tablicę symboli:
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]
Aby uzyskać bardziej ukierunkowaną listę, możesz usunąć metody wspólne dla wszystkich obiektów, np
p (f.methods - Object.methods).sort
#=> [:bar,:yay]
Alternatywnie możesz przekazać false
methods
lub public_methods
:
p f.methods(false) # public and protected singleton methods of `f`
#=> [:yay]
p f.public_methods(false)
#=> [:yay, :bar]
Możesz znaleźć prywatne i chronione metody obiektu za pomocą private_methods
i 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
#=> []
Podobnie jak w przypadku methods
i public_methods
, można przekazać false
do private_methods
i protected_methods
aby odciąć odziedziczonych metod.
Sprawdzanie klasy lub modułu
Oprócz methods
, public_methods
, protected_methods
i private_methods
, klasy i moduły udostępniają metody instance_methods
, public_instance_methods
, protected_instance_methods
i private_instance_methods
celu określenia metod ujawnionych dla obiektów dziedziczących po klasie lub module. Jak wyżej, możesz przekazać false
do tych metod, aby wykluczyć odziedziczone metody:
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]
Wreszcie, jeśli w przyszłości zapomnisz nazwy większości z nich, możesz znaleźć wszystkie te metody przy użyciu 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]
Wyświetl zmienne instancji obiektu
Możliwe jest zapytanie obiektu o jego zmienne instance_variables
za pomocą zmiennych_instancji, zmiennej_instancji_definowanej instance_variable_defined?
I instance_variable_get
i modyfikować je za pomocą instance_variable_set
i 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 #=> []
Nazwy zmiennych instancji zawierają symbol @
. Błąd zostanie pominięty:
f.instance_variable_defined?(:jim)
#=> NameError: `jim' is not allowed as an instance variable name
Zobacz zmienne globalne i lokalne
Kernel
ujawnia metody uzyskiwania listy global_variables
i 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]
W przeciwieństwie do zmiennych instancji nie ma metod specjalnie do uzyskiwania, ustawiania lub usuwania zmiennych globalnych lub lokalnych. Poszukiwanie takiej funkcjonalności jest zwykle znakiem, że kod należy przepisać, aby użyć skrótu do przechowywania wartości. Jeśli jednak musisz zmodyfikować zmienne globalne lub lokalne według nazwy, możesz użyć eval
z ciągiem znaków:
var = "$demo"
eval(var) #=> "in progress"
eval("#{var} = 17")
p $demo #=> 17
Domyślnie eval
oceni twoje zmienne w bieżącym zakresie. Aby ocenić zmienne lokalne w innym zakresie, musisz uchwycić powiązanie tam, gdzie istnieją zmienne lokalne.
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
W powyższym test_1
nie przekazał wiązania do zmiennej local_variable_get
, więc eval
został wykonany w kontekście tej metody, w której zmienna lokalna o nazwie foo
została ustawiona na :inside
.
Zobacz zmienne klasy
Klasy i moduły mają takie same metody introspekcji zmiennych instancji jak każdy inny obiekt. Klasa i moduły mają również podobne metody kwerendy o zmienne klas ( @@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
Podobnie jak zmienne instancji, nazwa zmiennych klasy musi zaczynać się od @@
, inaczej pojawi się błąd:
p Bar.class_variable_defined?( :instances )
#=> NameError: `instances' is not allowed as a class variable name