2010-03-17 95 views
18

如何像rails一样声明一个带关键字参数的方法。一些示例可能是方法的ruby关键字参数

Person.find(:all, :conditions => "..."). 

如何使用符号创建类似上述的方法?

我对ruby非常陌生。提前致谢!

+0

这些都是不是关键字参数。相反,您可以查看采用这些参数的方法的源代码,以了解如何实现此技术。查看关于'ActiveRecord :: Base.find'的文档(http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002263)获取想法。 – yfeldblum 2010-03-17 14:48:56

回答

37

Ruby实际上并没有关键字参数。 Rails利用了Ruby的一个特性,它可以让你省略哈希的大括号。例如,对于find,我们真正调用是:

但是如果哈希是方法的最后一个参数,你可以离开了括号和它仍然被视为一个哈希:

Person.find(:all, :conditions => "...", :offset => 10, :limit => 10) 

你可以在你自己的方法使用:

def explode(options={}) 
    defaults = { :message => "Kabloooie!", :timer => 10, :count => 1 } 
    options = defaults.merge(options) 

    options[:count].times do 
     sleep options[:timer] 
     puts options[:message] 
    end 
end 

然后调用它:

explode :message => "Meh.", :count => 3 

或者叫它不带参数,导致所有的默认值被使用:

explode 
+6

此答案现在(部分)已过时。 Ruby 2.0有真正的关键字参数。然而,它们与使用最后一个参数散列的惯例是狡猾的兼容:如果你将一个带有符号键的散列传递给一个期待关键字的方法,Ruby会将它们泼到关键字参数中。 Rails还没有使用Ruby 2.0的关键字参数来保持与Ruby 1.9的兼容性。 – Peeja 2013-11-14 15:46:39

0

由于红宝石是动态类型的,只是做:

def my_method(arg1, arg2) 
    #things 
end 

例如:

my_method(:test, {:somehash => "yay"}) 

my_method :test, :somehash => "yay" 

my_method(:test, :somehash => "yay") 
1

你只需要定义一个方法,其中的一个参数是一个哈希。这其实很简单。

def method(arg1, params) 
    name = params[:name] 
    number = params[:number] 

然后调用它像:

method(arg1, :name => 'Eric', :number => 2) 

有两点需要注意:

  1. 在Ruby中,你不需要包围的参数散列{}当你调用方法在大多数情况下,除非你像传递多个哈希一样复杂。在这种情况下,请确保您使用{}
  2. 环绕这些参数。Ruby是动态类型的,所以在定义方法时不需要说params是哈希。
6

我同意Samir Talwar和christopherwright所接受的答案。唯一潜在的缺点是,如果您使用不正确的关键字符号作为参数,或者在查找选项时没有收到警告,则最终会被忽略。如果这是你关心的问题,那么gem hash_keyword_args就可以解决它。成语是

def explode(opts={}) 
    opts = opts.keyword_args(:message => "Kabloooie!", :timer => 10, :count => 1) 

    opts.count.times do 
     sleep opts.timer 
     puts opts.message 
    end 
end 

注意使用存取方法,所以如果你错误地输入一个关键词,你会得到一个NoMethodError。和调用的行为是:

explode(:message => "Okay") # works 
explode(:msg => "Oops")  # raises ArgumentError 

宝石还为您提供了可能或可能不会在乎其他一些功能,如能够表明一个关键字是必需的。我一直在愉快地使用它一段时间。

(声明:我是宝石的作者)

7

由于红宝石2.0,红宝石does have keyword arguments

def my_method(arg1, name: 'defaultName', number: 0) 
    puts arg1, name, number 
end 
0

Ruby 2.0引入了真正的关键字参数,并且Ruby 2.1添加了必需的关键字参数。

那里https://chriszetter.com/blog/2012/11/02/keyword-arguments-in-ruby-2-dot-0/这个是一个很好的文章,我已经借了例子从那里:

红宝石2.0+:

def exclaim(text, exclamation: '!', number: 7) 
    text + exclamation * number 
end 

exclaim('hello', number: 4) #=> 'hello!!!!' 

# equivalent: 
exclaim('hello', {:number => 4}) #=> 'hello!!!!' 

红宝石2.1+:

def exclaim(text, exclamation: '!', number:) 
    text + exclamation * number 
end 

exclaim('Yo', number: 5) # => 'Yo!!!!!' 
exclaim('Yo') # raises: ArgumentError: missing keyword: number