Ruby ArgumentError:未知关键字,但不确定为什么

时间:2016-03-28 00:14:48

标签: ruby-on-rails ruby ruby-on-rails-plugins

我正在尝试制作一个简单的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 个答案:

答案 0 :(得分:1)

我认为您的问题可能是由*fields splat放在其他参数之前引起的。

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

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

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

在你的方法体中,你必须通过options hash引用变量, 即options[:foo]而不只是foo

当您致电该方法时,除非您没有向*fields传递任何内容 必须在你的选项参数中包含大括号。

例如:

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

而不是:

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

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

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

答案 1 :(得分:1)

你这样称呼 pmdb.getConnection(function(err, connection){ connection.query(query, function(err, rows){ if(err) { throw err; }else{ var jsonRows = []; for( var i in rows) { stringified = JSON.stringify(rows[i]); jsonRows.push(JSON.parse(stringified)); } connection.release(); aProject.achievements = jsonRows; upcomingTasks(aProject) } }); });

Carpet::Rendering

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

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

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