我正在学习rails并回到ruby来理解rails中的方法(以及ruby真正起作用)。当我看到方法调用时:
validates validates :first_name, :presence => true
我感到困惑。你如何在ruby中编写接受符号或哈希的方法。验证方法的源代码也令人困惑。有人可以简化这个主题,在我的ruby类和实例方法中使用符号作为参数吗?
更新:
好的@Dave!但我尝试的是:
def full_name (:first_name, :last_name)
@first_name = :first_name
@last_name = :last_name
p "#{@first_name} #{last_name}"
end
full_name("Breta", "Von Sustern")
这显然会引发错误。我试图理解:如果符号与任何其他值一样,为什么将这样的符号作为参数传递错误?
答案 0 :(得分:22)
符号和散列是与其他值相同的值,可以像任何其他值类型一样传递。
回想一下,ActiveRecord模型接受哈希作为参数;它最终与此类似(它不是这么简单,但它最终是相同的想法):
class User
attr_accessor :fname, :lname
def initialize(args)
@fname = args[:fname] if args[:fname]
@lname = args[:lname] if args[:lname]
end
end
u = User.new(:fname => 'Joe', :lname => 'Hacker')
除非你需要消除参数的歧义(并且当你跳过parens时还有一个块解析问题),这利用了不必将散列放在花括号{}
中。
类似地:
class TestItOut
attr_accessor :field_name, :validations
def initialize(field_name, validations)
@field_name = field_name
@validations = validations
end
def show_validations
puts "Validating field '#{field_name}' with:"
validations.each do |type, args|
puts " validator '#{type}' with args '#{args}'"
end
end
end
t = TestItOut.new(:name, presence: true, length: { min: 2, max: 10 })
t.show_validations
输出:
Validating field 'name' with:
validator 'presence' with args 'true'
validator 'length' with args '{min: 2, max: 10}'
从那里你可以开始看到这样的事情是如何运作的。
答案 1 :(得分:9)
我以为我会为Ruby 2+添加更新,因为这是我找到的'符号作为参数'的第一个结果。
从Ruby 2.0.0开始,您还可以在定义方法时使用符号。调用方法时,这些符号的行为与其他语言中的命名可选参数几乎相同。见下面的例子:
def variable_symbol_method(arg, arg_two: "two", arg_three: "three")
[arg, arg_two, arg_three]
end
result = variable_symbol_method :custom_symbol, arg_three: "Modified symbol arg"
# result is now equal to:
[:custom_symbol, "two", "Modified symbol arg"]
如示例所示,我们在调用方法时省略了arg_two:
,在方法体中,我们仍然可以将其作为变量arg_two
来访问。另请注意,函数调用确实改变了变量arg_three
。
答案 2 :(得分:5)
在Ruby中,如果在参数列表的末尾调用一堆name => value
对的方法,它们会自动包装在Hash
中并作为最后一个参数传递给您的方法:
def foo(kwargs)
p kwargs
end
>> foo(:abc=>"def", 123=>456)
{:abc=>"def", 123=>456}
>> foo("cabbage")
"cabbage"
>> foo(:fluff)
:fluff
关于你如何编写方法没有什么“特别”,这就是你如何称呼它。将常规Hash对象作为kwargs
参数传递是完全合法的。此语法快捷方式用于在API中实现命名参数。
Ruby符号只是一个值,因此在您的示例中,:first_name
只是一个常规的位置参数。 :presence
是用作哈希键的符号 - 任何类型都可以用作哈希键,但符号是一种常见的选择,因为它们是不可变的值。
答案 3 :(得分:2)
符号不仅限于哈希。它们是标识符,没有字符串的额外存储空间。这只是说“这是......”的一种方式。
验证调用的一个可能的函数定义可能是(只是为了简化,我不知道它的真正含义):
def validates(column, options)
puts column.to_s
if options[:presence]
puts "Found a presence option"
end
end
注意第一个符号是一个独立的参数,其余的是哈希值。
答案 4 :(得分:2)
我认为所有回复都没有提到问题;事实上,有人问我 - 我猜 - 不清楚符号是什么?
作为Ruby的新手,我有类似的困惑,对我来说,像下面这样的答案会更有意义
方法参数是由传入的值填充的局部变量。
您无法将符号用作自己的参数,因为您无法更改符号的值。