Ruby Language
introspektion
Sök…
Visa ett objekts metoder
Inspekterar ett objekt
Du kan hitta de offentliga metoderna som ett objekt kan svara på med antingen methods
eller public_methods
metoder som returnerar en rad symboler:
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]
För en mer riktad lista kan du ta bort metoder som är gemensamma för alla objekt, t.ex.
p (f.methods - Object.methods).sort
#=> [:bar,:yay]
Alternativt kan du skicka false
till methods
eller public_methods
:
p f.methods(false) # public and protected singleton methods of `f`
#=> [:yay]
p f.public_methods(false)
#=> [:yay, :bar]
Du kan hitta de privata och skyddade metoderna för ett objekt med private_methods
och 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
#=> []
Som med methods
och public_methods
kan du skicka false
till private_methods
och protected_methods
metoder för att private_methods
bort ärvda metoder.
Inspektera en klass eller modul
Förutom methods
, public_methods
, protected_methods
och private_methods
, klasser och moduler exponera instance_methods
, public_instance_methods
, protected_instance_methods
och private_instance_methods
att bestämma de metoder som exponeras för objekt som ärver från klassen eller modul. Som ovan kan du skicka false
till dessa metoder för att utesluta ärvda metoder:
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]
Slutligen, om du glömmer namnen på de flesta av dessa i framtiden, kan du hitta alla dessa metoder med hjälp av 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]
Visa ett objekts instansvariabler
Det är möjligt att fråga ett objekt om dess instansvariabler med instance_variables
, instance_variable_defined?
Och instance_variable_get
och ändra dem med instance_variable_set
och 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 #=> []
Namnen på instansvariabler inkluderar @
-symbolen. Du får ett fel om du utelämnar det:
f.instance_variable_defined?(:jim)
#=> NameError: `jim' is not allowed as an instance variable name
Visa globala och lokala variabler
Kernel
visar metoder för att få en lista över global_variables
och 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]
Till skillnad från instansvariabler finns det inga metoder specifikt för att få, ställa in eller ta bort globala eller lokala variabler. Att leta efter sådan funktionalitet är vanligtvis ett tecken på att din kod ska skrivas om för att använda en Hash för att lagra värdena. Men om du måste ändra globala eller lokala variabler med namn kan du använda eval
med en sträng:
var = "$demo"
eval(var) #=> "in progress"
eval("#{var} = 17")
p $demo #=> 17
Som standard kommer eval
att utvärdera dina variabler i det aktuella omfånget. För att utvärdera lokala variabler i ett annat omfång måste du fånga bindningen där de lokala variablerna finns.
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
I det ovannämnda test_1
inte en bindning till local_variable_get
, och eval
utfördes därför inom ramen för den metoden, där en lokal variabel med namnet foo
var inställd på :inside
.
Visa klassvariabler
Klasser och moduler har samma metoder för introspekterande instansvariabler som alla andra objekt. Klass och moduler har också liknande metoder för att fråga klassvariablerna ( @@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
I likhet med instansvariabler måste namnet på klassvariabler börja med @@
, så får du ett fel:
p Bar.class_variable_defined?( :instances )
#=> NameError: `instances' is not allowed as a class variable name