How to retrieve a class name?

2019-06-05 20:26发布

I am using Ruby on Rails 3.0.7 and I would like to retrieve the class name, also if it is namespaced. For example, if I have a class named User::Profile::Manager I would retrieve the Manager string from that using some unknown to me Ruby or Ruby on Rails method and in a secure way.

BTW: What other "usefull" information that are "commonly" used can I get for the class?

3条回答
戒情不戒烟
2楼-- · 2019-06-05 20:50

Some useful simple metaprogramming calls:

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

If you want the lowest-level class from User::Profile::Manager I'd probably do the following [using a regex for this seems like overkill to me ;)]:

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

Edit:

If you actually want to look through some more metaprogramming calls, check the docs for the Object and Module classes, and check out the google results for "Ruby Metaprogramming".

查看更多
Deceive 欺骗
3楼-- · 2019-06-05 20:53

To expand on @JCorcuera's answer, some other useful information can be found with kind_of? and methods

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
查看更多
做自己的国王
4楼-- · 2019-06-05 20:54

Have you tried class method:

class A
  class B
  end
end

myobject = A::B.new

myobject.class

=> A::B
查看更多
登录 后发表回答