Ruby, эквивалентный из “dir” Python?

Чтобы описать это, сначала давайте понять, как хранятся локальные переменные и объекты.

Локальная переменная хранится в стеке: enter image description here [/g1]

Если вы посмотрели на изображении вы должны понимать, как все работает.

Когда вызов функции вызывается Java-приложением, стек стека выделяется в стеке вызовов. Фрейм стека содержит параметры вызываемого метода, его локальные параметры и обратный адрес метода. Адрес возврата обозначает точку выполнения, из которой выполнение программы должно продолжаться после возврата вызванного метода. Если нет места для нового стека кадров, то StackOverflowError вызывается виртуальной машиной Java (JVM).

Наиболее распространенным случаем, который может исчерпать стек Java-приложения, является рекурсия. В рекурсии метод запускается во время его выполнения. Рекурсия рассматривается как мощный метод программирования общего назначения, но ее следует использовать с осторожностью, чтобы избежать StackOverflowError.

Пример, показывающий StackOverflowError, показан ниже:

StackOverflowErrorExample.java:

public class StackOverflowErrorExample {

    public static void recursivePrint(int num) {
        System.out.println("Number: " + num);

        if(num == 0)
            return;
        else
            recursivePrint(++num);
    }

    public static void main(String[] args) {
        StackOverflowErrorExample.recursivePrint(1);
    }
}

В этом примере мы определяем рекурсивный метод, называемый recursivePrint, который печатает целое число, а затем вызывает себя со следующим последовательным целым числом в качестве аргумента. Рекурсия заканчивается, пока мы не перейдем в 0 в качестве параметра. Однако в нашем примере мы передали параметр из 1 и его увеличивающих последователей, следовательно, рекурсия никогда не завершится.

Пример выполнения с использованием флага -Xss1M, который определяет размер стека потоков ниже 1MB, показано ниже:

Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
        at java.io.PrintStream.write(PrintStream.java:480)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.write(PrintStream.java:527)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:806)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        ...

В зависимости от начальной конфигурации JVM результаты могут отличаться, но в конечном итоге следует вызывать StackOverflowError. Этот пример является очень хорошим примером того, как рекурсия может вызвать проблемы, если не выполнять их с осторожностью.

Как работать с StackOverflowError

  1. Простейшим решением является тщательная проверка трассировки стека и обнаружение повторяющегося шаблона номеров строк. Эти номера строк указывают, что код рекурсивно называется. Как только вы обнаружите эти строки, вы должны тщательно проверить свой код и понять, почему рекурсия никогда не заканчивается.
  2. Если вы подтвердили правильность реализации рекурсии, вы можете увеличить размер стека, чтобы разрешить большее количество вызовов. В зависимости от установленной виртуальной машины Java (JVM) размер стека по умолчанию может равняться либо 512 КБ, либо 1 МБ. Вы можете увеличить размер стека потоков, используя флаг -Xss. Этот флаг можно указать либо через конфигурацию проекта, либо через командную строку. Формат аргумента -Xss: -Xss<size>[g|G|m|M|k|K]
50
задан nosklo 22 January 2009 в 10:16
поделиться

8 ответов

Мне нравится иметь это в моем .irbrc:

class Object
  def local_methods
    (methods - Object.instance_methods).sort
  end
end

Таким образом, когда я нахожусь в irb:

>> Time.now.local_methods 
=> ["+", "-", "<", "<=", "<=>", ">", ">=", "_dump", "asctime", "between?", "ctime", "day", "dst?", "getgm", "getlocal", "getutc", "gmt?", "gmt_offset", "gmtime", "gmtoff", "hour", "isdst", "localtime", "mday", "min", "mon", "month", "sec", "strftime", "succ", "to_f", "to_i", "tv_sec", "tv_usec", "usec", "utc", "utc?", "utc_offset", "wday", "yday", "year", "zone"]

Или еще более милый - с grep:

>> Time.now.local_methods.grep /str/
=> ["strftime"]
20
ответ дан Commander Keen 7 November 2019 в 10:58
поделиться

Насколько я знаю не точно, но Вы добираетесь где-нибудь с

object.methods.sort
54
ответ дан Jonas Elfström 7 November 2019 в 20:58
поделиться

Можно взять модуль, такой как Enumerable, и отправить methods метод, который перечисляет все методы, которые определяет модуль. Классы, которые включают этот модуль, ответят на эти методы.

>> Enumerable.methods
=> ["inspect", "private_class_method", "const_missing", "clone", "method", "public_methods", "public_instance_methods", "instance_variable_defined?", "method_defined?", "equal?", "freeze", "included_modules", "const_get", "yaml_as", "methods", "respond_to?", "module_eval", "class_variables", "dup", "protected_instance_methods", "instance_variables", "public_method_defined?", "__id__", "object_id", "taguri", "yaml_tag_read_class", "eql?", "const_set", "id", "to_yaml", "taguri=", "singleton_methods", "send", "class_eval", "taint", "frozen?", "instance_variable_get", "include?", "private_instance_methods", "__send__", "instance_of?", "private_method_defined?", "to_a", "name", "to_yaml_style", "autoload", "type", "yaml_tag_class_name", "<", "protected_methods", "instance_eval", "<=>", "==", ">", "display", "===", "instance_method", "instance_variable_set", "to_yaml_properties", "kind_of?", "extend", "protected_method_defined?", "const_defined?", ">=", "ancestors", "to_s", "<=", "public_class_method", "hash", "class", "instance_methods", "tainted?", "=~", "private_methods", "class_variable_defined?", "nil?", "untaint", "constants", "autoload?", "is_a?"]
4
ответ дан dylanfm 7 November 2019 в 20:58
поделиться

Подсказка для "поиска" метода в irb:

"something".methods.select {|item| item =~ /query/ }

Подсказка для испытания методов на значении для сравнения:

value = "something"
[:upcase, :downcase, :capitalize].collect {|method| [method, value.send(method)] }

кроме того, обратите внимание, что Вы не станете всеми одинаковыми информация как dir Python с object.methods. Необходимо использовать комбинацию object.methods и class.constants, также класс singleton_methods для получения методов класса.

4
ответ дан method 7 November 2019 в 20:58
поделиться

Едва ли. Как другие сказал, можно получить часть того, что Вы хотите путем списка методов экземпляров классов (например, String.instance_methods), но это не помогает Вам, если файл, который Вы открываете, вновь открыл класс (если Вы не проверяете прежде и после).

, Если Вам не нужен программируемый доступ к списку методов, рассмотрите проверку документации для класса, модуля или метода с помощью ri инструмент командной строки.

0
ответ дан rampion 7 November 2019 в 20:58
поделиться

Я пошел бы для чего-то вроде этого:

y String.methods.sort

, Который даст Вам yaml представление сортированного массива методов. Обратите внимание, что это может использоваться для списка методов и классов и объектов.

1
ответ дан Codebeef 7 November 2019 в 20:58
поделиться

Я сделал бы это комментарием к ответу jonelf, но по-видимому у меня нет достаточного количества представителя

some_object.methods.sort - Object.new.methods

, Это не точно, что Вы спрашивали, как другие сказали, но это дает Вам информацию, которая Вы после.

0
ответ дан jshen 7 November 2019 в 20:58
поделиться

Если я, stricly читают Ваш вопрос, я должен ответить на него тот путь: файл, как определено require в Ruby является просто контейнером и не имеет, обязательно имеют любое отношение с классом. Содержание может быть:

  • класс
  • модуль
  • простой код

или любая комбинация вышеупомянутого, несколько раз. Таким образом, Вы не можете непосредственно попросить все методы в данном файле.

, Если Вы означали перечислять все методы данного модуля или класса, тогда другие ответы - то, что Вы ищете (главным образом использование #methods метод на имени модуля или классе).

0
ответ дан Keltia 7 November 2019 в 20:58
поделиться