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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow