Как получить общедоступные методы класса без унаследованных методов?

Учитывая любой объект, я могу вызвать #public_methods и увидеть все методы, на которые он будет реагировать. Тем не менее, я считаю, что иногда было бы удобно получить краткий список всех общедоступных методов, которые не унаследованы, то есть того, что действительно является частью этого класса.

Я нашел в "простой способ перечислить общедоступные методы для Ruby. объект", что если я использую:

(Foo.public_methods - Object.public_methods).sort

Я могу отфильтровать множество базовых вещей Ruby. Я хотел бы иметь возможность фильтровать все, что было унаследовано по всей цепочке. Если я знаю родительский класс, я могу фильтровать его, но я хотел бы придумать универсальную команду, которая могла бы возвращать массив неунаследованных общедоступных методов для любого объекта.


person Andrew    schedule 13.01.2012    source источник


Ответы (2)


Просто передайте false в качестве аргумента inherited для public_methods:

"hello".public_methods.include?(:dup) # => true
"hello".public_methods(false).include?(:dup) # => false

Не ответ на ваш вопрос, но, если вы не знали, irb выполняет автозаполнение, поэтому легко получить список общедоступных методов (особенно если вы знаете начало метода, который ищете). Просто нажмите вкладку; при двойном нажатии будут перечислены все возможности (включая унаследованные):

> "nice".d<tab><tab>
"nice".delete      "nice".delete!    "nice".display   "nice".downcase                 
"nice".downcase!   "nice".dump       "nice".dup       "nice".define_singleton_method

> "nice".<tab><tab>
Display all 162 possibilities? (y or n)
...

Использование pry еще больше упрощает просмотр доступных методов с разбивкой по уровням наследования:

[1] pry(main)> cd "nice"
[2] pry("nice"):1> ls
Comparable#methods: <  <=  >  >=  between?
String#methods: %  *  +  <<  <=>  ==  ===  =~  []  []=  ascii_only?  bytes  bytesize  byteslice  capitalize  capitalize!  casecmp  center  chars  chomp  chomp!  chop  chop!  chr  clear  codepoints  concat  count  crypt  delete  delete!  downcase  downcase!  dump  each_byte  each_char  each_codepoint  each_line  empty?  encode  encode!  encoding  end_with?  eql?  force_encoding  getbyte  gsub  gsub!  hash  hex  include?  index  insert  inspect  intern  length  lines  ljust  lstrip  lstrip!  match  next  next!  oct  ord  partition  prepend  replace  reverse  reverse!  rindex  rjust  rpartition  rstrip  rstrip!  scan  setbyte  shellescape  shellsplit  size  slice  slice!  split  squeeze  squeeze!  start_with?  strip  strip!  sub  sub!  succ  succ!  sum  swapcase  swapcase!  to_c  to_f  to_i  to_r  to_s  to_str  to_sym  tr  tr!  tr_s  tr_s!  unpack  upcase  upcase!  upto  valid_encoding?
locals: _  _dir_  _ex_  _file_  _in_  _out_  _pry_
person Marc-André Lafortune    schedule 13.01.2012
comment
вы имели в виду irb или irc? :-) - person Sergio Tulentsev; 13.01.2012
comment
Действительно, irb. Спасибо тебе и @Mu - person Marc-André Lafortune; 13.01.2012
comment
О, супер полезно! Я не знал, что #public_methods принимает какие-либо аргументы, и мне даже не пришло в голову проверить. Спасибо! - person Andrew; 13.01.2012

Взгляните на Module#instance_methods. Этот метод имеет один логический аргумент include_super, возвращать ли также унаследованные методы. Значение по умолчанию — истина.

Вы можете использовать следующее:

class A 
  def method_1
     puts "method from A"
  end
end

class B < A
  def method_2
    puts "method from B"
  end
end

B.instance_methods        # => [:method_1, :method_2, ...]
B.instance_methods(false) # => [:method_2]
person Marshall Shen    schedule 08.01.2014
comment
Кстати, аналогичный метод для Object называется public_methods, см. ruby-doc.org/core-2.5.1/Object.html#method-i-public_method. Метод instance_methods находится в Module, см. ruby-doc .org/core-2.5.1/Module.html#method-i-instance_methods. - person Jochem Schulenklopper; 16.09.2018