首页 文章

Ruby ArgumentError:未知关键字,但不确定原因

提问于
浏览
1

我正在尝试制作一个简单的Ruby on Rails插件 . 当使用hash_opts的哈希调用redcarpetable函数时,我得到“ArgumentError:unknown keyword:render_opts” . 功能代码:

def redcarpetable(*fields, renderer: :default, as: [nil], prefix: "rendered", render_opts: {})
    fields.each do |field|
      if fields.count > 1
        define_method "#{prefix}_#{field}" do
        Carpet::Rendering.render(read_attribute(field), renderer_opts: render_opts, rc_renderer: renderer).html_safe
        end # End defining the method dynamically.
      else
        if as[0]
          as.each do |method_name|
            define_method "#{method_name}" do
            Carpet::Rendering.render(read_attribute(field), render_opts: render_opts, rc_renderer: renderer).html_safe
            end # End defining the method dynamically.
          end
        else
          define_method "rendered_#{field}" do
          Carpet::Rendering.render(read_attribute(field), render_opts: render_opts, rc_renderer: renderer).html_safe
          end # End defining the method dynamically.
        end
      end
    end # End the fields loop.
  end # End the redcarpet method.

如何调用该函数:

redcarpetable :name, renderer: :simple_parser, as: [:cool_name, :rendered_name], render_opts: {:generate_toc_data: true}

为了允许渲染选项的哈希,必须对函数声明做什么?完整代码(未详细记录或重构)是here .

2 回答

  • 1

    你这样称呼 Carpet::Rendering

    Carpet::Rendering.render(read_attribute(field), 
      render_opts: render_opts, rc_renderer: renderer
    ).html_safe
    

    但该选项实际上称为renderer_opts . 只需将其更改为:

    Carpet::Rendering.render(read_attribute(field), 
      renderer_opts: render_opts, rc_renderer: renderer
    ).html_safe
    

    您可能还想在方法的签名中更改它 .

  • 1

    我认为你的问题可能是由于将 *fields splat放在其他参数之前 .

    虽然我不确定是什么导致了您的错误,但您可以使用以下方法获取选项哈希:

    def redcarpetable(options={}, *fields)
      defaults = {
        foo: "bar",
        bar: "foo"
      }
      options= defaults.merge(options)
      puts options[:foo] # => "bar"
    end
    

    这样,您可以设置默认值并在调用方法时覆盖它们 .

    在您的方法体中,您将不得不通过选项哈希引用变量,即 options[:foo] 而不仅仅是 foo .

    当你调用方法时,除非你没有传递给 *fields ,否则你必须在你的options参数中包含大括号 .

    例如:

    redcarpetable({foo: bar}, ["field1" "field2"]
    

    并不是:

    redcarpetable(foo: bar, ["field1, "field2"]
    

    此外,如果您传递任何字段但未传递任何选项,则必须包含空括号:

    redcarpetable({}, ["field1", "field2"])
    

相关问题