Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Объектное пространство each_object могло быть тем, что Вы ищете.
Для получения списка включенных модулей Вы могли использовать Модуль included_modules .
можно ли также проверить, отвечает ли объект на метод в зависимости от конкретного случая с помощью объект respond_to? .
dir()
метод не ясно определен ...
Примечание: , поскольку
dir()
предоставляется, прежде всего, как удобство для использования при интерактивной подсказке, оно пытается предоставить интересный набор имен больше, чем оно пытается предоставить строго или последовательно определяемый набор имен, и его подробное поведение может измениться через выпуски.
..., но мы можем создать близкое приближение в Ruby. Давайте сделаем метод, который возвратит отсортированный список всех методов, добавленных к нашему объему включенными модулями. Мы можем получить список модулей, которые были включены при помощи included_modules
метод.
Как dir()
, мы хотим проигнорировать методы "по умолчанию" (как print
), и мы также хотим сфокусироваться на "интересном" наборе имен. Так, мы проигнорируем методы в Kernel
, и мы будем только методы возврата, которые были определены непосредственно в модулях, игнорируя унаследованные методы. Мы можем выполнить позже путем передачи false
в methods()
метод. Соединение всего этого мы добираемся...
def included_methods(object=self)
object = object.class if object.class != Class
modules = (object.included_modules-[Kernel])
modules.collect{ |mod| mod.methods(false)}.flatten.sort
end
можно передать его класс, объект или ничто (это принимает значение по умолчанию к текущей области). Давайте испытаем его...
irb(main):006:0> included_methods
=> []
irb(main):007:0> include Math
=> Object
irb(main):008:0> included_methods
=> ["acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "cos", "cosh", "erf", "erfc", "exp", "frexp", "hypot", "ldexp", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"]
<час> dir()
также включает локально определенные переменные, и это - легкое. Просто звоните...
local_variables
..., к сожалению, мы не можем только добавить эти local_variables
вызов к [1 114], потому что он дал бы нам переменные, которые локальны для included_methods
метод, и это не было бы очень полезно. Так, если Вы хотите локальные переменные, включенные с included_methods, просто звоните...
(included_methods + local_variables).sort
Для доступа ко всем экземплярам объектов в рубине, Вы используете ObjectSpace
http://www.ruby-doc.org/core-1.8.7/classes/ObjectSpace.html#M000928
Однако, это считают медленным (даже для рубина) и нельзя включить в некоторых интерпретаторах (например, jRuby может отключить ObjectSpace, поскольку это намного быстрее полагается в jvm для gc, не будучи должен отследить этот материал в jRuby).
Можно передать сообщения .methods библиотеке/модулю даже прежде, чем загрузить его, видеть все доступные методы. Выполнение self.methods
просто возвраты все методы, которые содержит Объектный объект. Вы видите это путем выполнения self.class
. Так скажем, Вы хотите видеть все методы в модуле Файла. Вы просто делаете File.methods
, и Вы получите список всех методов, которые существуют в модуле Файла. Это, возможно, не то, что Вы хотите, но это должно быть несколько полезно.
Я не совсем уверен в том, что Вы подразумеваете под 'текущими объектами'. Можно выполнить итерации по ObjectSpace, как уже был упомянут. Но вот несколько других методов.
local_variables
instance_variables
global_variables
class_variables
constants
Существует один глюк. Их нужно назвать в правильных объемах. Так прямо в IRB, или в экземпляре объекта или в объеме класса (так везде, в основном) можно назвать первые 3.
local_variables #=> ["_"]
foo = "bar"
local_variables #=> ["_", "foo"]
# Note: the _ variable in IRB contains the last value evaluated
_ #=> "bar"
instance_variables #=> []
@inst_var = 42
instance_variables #=> ["@inst_var"]
global_variables #=> ["$-d", "$\"", "$$", "$<", "$_", ...]
$" #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]
Но umm, что, если Вы хотите, чтобы Ваша программа на самом деле оценила их, не нуждаясь в Вас для ввода их manyally? Прием является оценкой.
eval "@inst_var" #=> 42
global_variables.each do |v|
puts eval(v)
end
Последние 2 из этих 5, упомянутых вначале, должны быть оценены на уровне модуля (класс является потомком модуля, так, чтобы работы).
Object.class_variables #=> []
Object.constants #=> ["IO", "Duration", "UNIXserver", "Binding", ...]
class MyClass
A_CONST = 'pshh'
class InnerClass
end
def initialize
@@meh = "class_var"
end
end
MyClass.constants #=> ["A_CONST", "InnerClass"]
MyClass.class_variables #=> []
mc = MyClass.new
MyClass.class_variables #=> ["@@meh"]
MyClass.class_eval "@@meh" #=> "class_var"
Вот, еще несколько приемов для исследования в различных направлениях
"".class #=> String
"".class.ancestors #=> [String, Enumerable, Comparable, ...]
String.ancestors #=> [String, Enumerable, Comparable, ...]
def trace
return caller
end
trace #=> ["(irb):67:in `irb_binding'", "/System/Library/Frameworks/Ruby...", ...]