在Ruby中,如何验证结构体的身份?

jobtbby3  于 2023-05-17  发布在  Ruby
关注(0)|答案(1)|浏览(72)

我一直在尝试理解Ryan Bates在他的Presenters RailsCast(#287 Presenters from Scratch (pro) - RailsCasts)中使用的present方法中的self类。在视频中,Ryan说,“Self是一个模板对象,它拥有我们想要访问的所有helper方法”,但我想知道这个对象的类。在阅读了一系列博客文章、SO线程和Ruby文档之后,我开始认为self是一种Struct,但我不知道如何证实这一观点。
我的问题是:**1)在下面的present方法中,selfStruct吗?,以及2)**如何验证某个东西是Struct?

module ApplicationHelper
  def present(object, klass = nil)
    klass ||= "#{object.class}Presenter".constantize
    presenter = klass.new(object, self)
    yield presenter if block_given?
    presenter
  end
end

我问这个问题是因为我没有太多使用Struct类的经验,当我在上面的方法中间插入binding.pry并试图获取self的类名时,我最终会遇到更多的问题。

  • 当我输入self.class时,我得到#<Class:0x007fb64f696268> * 我想知道在这里得到Class是否表明我有一个Struct,但我找不到任何文档来证实这一点 *
  • 当我输入self.class.class时,我得到Class
  • 当我输入self时,我得到一个扩展对象,它以下面列出的代码行开始
@ line 16 ApplicationHelper#present:

14: def present(object, klass = nil)
15:   klass ||= "#{object.class}Presenter".constantize
16:   binding.pry
17:   presenter = klass.new(object, self)
18:   yield presenter if block_given?
19: end

[1] pry(#<#<Class:0x007fb64f696268>>)> self
=> #<#<Class:0x007fb64f696268>:0x007fb64f6948f0
@_assigns={"marked_for_same_origin_verification"=>true},
@_config={},
@_controller=
  #<PostsController:0x007fb64f6762d8
   @_action_has_layout=true,
   @_action_name="show",
   @_config={},
   @_db_runtime=0,
   @_lookup_context=
    #<ActionView::LookupContext:0x007fb64f6760d0
      @cache=true,
      @details=
        {:locale=>[:en],
        :formats=>[:html],
        :variants=>[],
        :handlers=>[:raw, :erb, :html, :builder, :ruby]},
      @details_key=#<Concurrent::Map:0x007fb64f697938 entries=0 default_proc=nil>,
      @prefixes=["posts", "application"],
      @rendered_format=:html,
      @view_paths=
        #<ActionView::PathSet:0x007fb64f675fe0

这个post在解释Struct是如何工作的方面很有帮助,但没有解释如何确认它们有一个Struct。
最初,当我开始剖析present方法时,我发现这个answer很有帮助。然而,我被评论所迷惑,说“ModelPresenter是通过传递模型和ApplicationHelper类来初始化的”,因为ApplicationHelper是一个模块。

lokaqttq

lokaqttq1#

摘要

使用is_a?(Struct)

说明

struct是匿名类的构造函数:

struct_class = Struct.new(:foo)
# => #<Class:0x007fa7e006ea98>

你可以检查匿名类的示例是否是一个结构体,如下所示:

inst = struct_class.new
inst.class.superclass
# => Struct

但是Object#is_a?会检查父类 * 以及 * 超类:

inst.is_a?(Struct)
# => true

您可以在以下任意示例中看到相同的行为:

# inherits from String
anon_class = Class.new(String) 

inst = anon_class.new
# => ""

inst.class == String
# => false

inst.is_a?(String)
# => true

相关问题