Как получить открытые методы класса без унаследованных методов? - PullRequest
32 голосов
/ 13 января 2012

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

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

(Foo.public_methods - Object.public_methods).sort

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

Ответы [ 2 ]

56 голосов
/ 13 января 2012

Просто передайте 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_
8 голосов
/ 08 января 2014

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

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

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]
...