Как получить имя класса? - PullRequest
1 голос
/ 14 июня 2011

Я использую Ruby on Rails 3.0.7, и я хотел бы получить имя класса, даже если оно находится в пространстве имен. Например, если у меня есть класс с именем User::Profile::Manager, я извлеку из него строку Manager, используя неизвестный мне метод Ruby или Ruby on Rails, и безопасный способ.

КСТАТИ : Какую другую "полезную" информацию, которая "обычно" используется, я могу получить для класса?

Ответы [ 3 ]

3 голосов
/ 14 июня 2011

Некоторые полезные простые вызовы метапрограммирования:

user = User::Profile::Manager.new(some_params)
user.class # => User::Profile::Manager
user.class.class # => Class
user.class.name # => "User::Profile::Manager"
user.class.name.class # => String

# respond_to? lets you know if you can call a method on an object or if the method you specify is undefined
user.respond_to?(:class) # => true
user.respond_to?(:authenticate!) # => Might be true depending on your authentication solution
user.respond_to?(:herpderp) # => false (unless you're the best programmer ever)

# class.ancestors is an array of the class names of the inheritance chain for an object
# In rails 3.1 it yields this for strings:
"string".class.ancestors.each{|anc| puts anc}

String
JSON::Ext::Generator::GeneratorMethods::String
Comparable
Object
PP::ObjectMixin
JSON::Ext::Generator::GeneratorMethods::Object
ActiveSupport::Dependencies::Loadable
Kernel
BasicObject

Если вам нужен класс самого низкого уровня из User::Profile::Manager, я бы, вероятно, сделал следующее [использование регулярного выражения для этого кажется мне излишним;)]:

user = User::Profile::Manager.new
class_as_string = user.class.name.split('::').last # => "Manager"
class_as_class = class_name.constantize # => Manager

Edit:

Если вы действительно хотите просмотреть еще несколько вызовов метапрограммирования, проверьте документы для классов Object и Module и проверьте результаты Google для "Ruby Metaprogramming".

2 голосов
/ 14 июня 2011

Вы пробовали class метод:

class A
  class B
  end
end

myobject = A::B.new

myobject.class

=> A::B
1 голос
/ 14 июня 2011

Чтобы расширить ответ @ JCorcuera, некоторую другую полезную информацию можно найти с помощью kind_of?и методы

class A
  class B
        def foo
        end
  end
end

myobject = A::B.new

p myobject.class
=> A::B

p myobject.kind_of? A::B
=> true

p myobject.methods
=> [:foo, :nil?, :===, :=~, ...

p myobject.methods.include? :foo
=> true
...