Ruby Language
Zelfreflectie
Zoeken…
Bekijk de methoden van een object
Een object inspecteren
U kunt de openbare methoden vinden waarop een object kan reageren met behulp van de methods
of de methods
public_methods
, die een reeks symbolen retourneren:
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]
Voor een meer gerichte lijst kunt u methoden verwijderen die gemeenschappelijk zijn voor alle objecten, bijv
p (f.methods - Object.methods).sort
#=> [:bar,:yay]
Als alternatief kunt u false
doorgeven aan methods
of public_methods
:
p f.methods(false) # public and protected singleton methods of `f`
#=> [:yay]
p f.public_methods(false)
#=> [:yay, :bar]
U kunt de private en beschermde methoden van een object vinden met private_methods
en 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
#=> []
Net als bij methods
en public_methods
, kunt u false
doorgeven aan private_methods
en protected_methods
om geërfde methoden weg te knippen.
Een klasse of module inspecteren
Naast methods
, public_methods
, protected_methods
en private_methods
, leggen klassen en modules instance_methods
, public_instance_methods
, protected_instance_methods
en private_instance_methods
bloot om de blootgestelde methoden te bepalen voor objecten die erven van de klasse of module. Zoals hierboven, kunt u false
doorgeven aan deze methoden om geërfde methoden uit te sluiten:
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]
Als u ten slotte de namen van de meeste hiervan in de toekomst vergeet, kunt u al deze methoden vinden met behulp van 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]
Instantievariabelen van een object bekijken
Het is mogelijk om een object over zijn instantievariabelen te vragen met behulp van instance_variables
, instance_variable_defined?
en instance_variable_get
, en wijzig ze met behulp van instance_variable_set
en 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 #=> []
De namen van instantievariabelen bevatten het @
-symbool. U krijgt een foutmelding als u deze weglaat:
f.instance_variable_defined?(:jim)
#=> NameError: `jim' is not allowed as an instance variable name
Bekijk globale en lokale variabelen
De Kernel
onthult methoden voor het verkrijgen van de lijst met global_variables
en 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]
In tegenstelling tot instantievariabelen zijn er geen specifieke methoden voor het ophalen, instellen of verwijderen van globale of lokale variabelen. Zoeken naar dergelijke functionaliteit is meestal een teken dat uw code moet worden herschreven om een hash te gebruiken om de waarden op te slaan. Als u echter globale of lokale variabelen op naam moet wijzigen, kunt u eval
met een tekenreeks:
var = "$demo"
eval(var) #=> "in progress"
eval("#{var} = 17")
p $demo #=> 17
Standaard evalueert eval
uw variabelen in het huidige bereik. Om lokale variabelen in een ander bereik te evalueren, moet u de binding vastleggen waar de lokale variabelen bestaan.
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
In de bovenstaande test_1
niet voorbij een binding aan local_variable_get
en dus de eval
werd uitgevoerd binnen het kader van deze werkwijze, waarbij een lokale variabele genaamd foo
werd ingesteld :inside
.
Bekijk klassenvariabelen
Klassen en modules hebben dezelfde methoden voor het introspecteren van instantievariabelen als elk ander object. Klasse en modules hebben ook vergelijkbare methoden voor het doorzoeken van de klassenvariabelen ( @@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
Net als bij instantievariabelen, moet de naam van klassenvariabelen beginnen met @@
, of u krijgt een foutmelding:
p Bar.class_variable_defined?( :instances )
#=> NameError: `instances' is not allowed as a class variable name