Има ли начин в Ruby да отпечатате публичните методи на обект

... без да включва всички публични методи на генеричния обект? Искам да кажа, различно от извършване на изваждане на масив. Просто искам бързо да прегледам какво ми е достъпно от даден обект понякога, без да влизам в документите.


person AKWF    schedule 15.11.2011    source източник


Отговори (4)


methods, instance_methods, public_methods, private_methods и protected_methods всички приемат булев параметър, за да определят дали методите на родителите на вашия обект са включени.

Например:

ruby-1.9.2-p0 > class MyClass < Object; def my_method; return true; end; end;
ruby-1.9.2-p0 > MyClass.new.public_methods
 => [:my_method, :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :initialize_dup, :initialize_clone, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :respond_to_missing?, :extend, :display, :method, :public_method, :define_singleton_method, :__id__, :object_id, :to_enum, :enum_for, :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__] 
ruby-1.9.2-p0 > MyClass.new.public_methods(false)
 => [:my_method]

Както е отбелязано от @Marnen, методите, дефинирани динамично (напр. с method_missing), няма да се показват тук. Единственият ви залог за тези е да се надявате, че библиотеките, които използвате, са добре документирани.

person Benoit Garret    schedule 15.11.2011
comment
Може би вместо това трябва да промените примера си с нещо като ''.public_methods или [].public_methods. Очевидно е за всеки, който познава Ruby, че вашият пример изброява методите, на които самият обект от клас Array отговаря, а не методите на екземпляра на класа Array, но може да е подвеждащ на новаци. - person Jörg W Mittag; 15.11.2011
comment
@JörgWMittag благодаря за приноса. Отидох с персонализиран клас, защото екземплярът Array или String има твърде много методи и блоковете на SO кода не обвиват редове. Не беше веднага ясно, че резултатите не са същите. - person Benoit Garret; 15.11.2011

Това ли е резултатът, който търсихте?

class Foo
  def bar
    p "bar"
  end
end

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


ps Предполагам, че това не е резултатът, който преследвахте:

p Foo.public_methods(false)          # => [:allocate, :new, :superclass]
person Sean Vikoren    schedule 15.11.2011

Започнах да се опитвам да документирам всички тези методи за проверка в един момент в https://github.com/bf4/Notes/blob/master/code/ruby_inspection.rb

Както е отбелязано в други отговори:

class Foo; def bar; end; def self.baz; end; end

Първо, обичам да сортирам методите

Foo.public_methods.sort # all public instance methods
Foo.public_methods(false).sort # public class methods defined in the class
Foo.new.public_methods.sort # all public instance methods
Foo.new.public_methods(false).sort # public instance methods defined in the class

Полезен съвет Grep, за да разберете какви са вашите възможности

Foo.public_methods.sort.grep /methods/ # all public class methods matching /method/
# ["instance_methods", "methods", "private_instance_methods", "private_methods", "protected_instance_methods", "protected_methods", "public_instance_methods", "public_methods", "singleton_methods"]
Foo.new.public_methods.sort.grep /methods/
#  ["methods", "private_methods", "protected_methods", "public_methods", "singleton_methods"]

Вижте също https://stackoverflow.com/questions/123494/whats-your-favourite-irb-trick

person BF4    schedule 16.11.2011

Ако имаше, нямаше да е много полезно: често публичните методи не са единствените ви възможности, поради способността на Ruby да фалшифицира методи чрез динамично метапрограмиране. Така че не можете наистина да разчитате на instance_methods да ви каже много полезни неща.

person Marnen Laibow-Koser    schedule 15.11.2011