我曾经更像是一个业余爱好的Java人,现在尝试切换到Ruby on Rails。 但是我有一些困难,信不信由你,我喜欢大括号和分号......给了一些方向。
但问题是: 现在我正在参加RoR的在线课程,它发生在我身上,我对如何使用符号,哈希等总是错误的。
示例1: 让我们来看看这一行代码:
form_for(:session, :html => {class: "form-horizontal", role: "form"}, url: login_path)
这就是我读它的方式:
方法/功能名称是
form_for
解析为此方法的参数是:
:session, :html => {class: "form-horizontal", role: "form"}, url: login_path
让我们将其分解为
:session
:html => {class: "form-horizontal", role: "form"}
url: login_path
我该怎么知道如何申报这些参数? 为什么:session和:html passend作为键和url而不是? :html符号是Hashmap符号吗?
在模型文件中,您声明了这样的n:m关系(例如用户< - >股票)
has_many :users, through: :user_stocks
好的,我知道第一个参数是:用户,第二个参数与
相同:through => :user_stocks
正确?
但是以同样的方式,让我们看看同一个项目中的routes.rb配置:
resources :user_stocks, except: [:show, :edit, :update]
现在我们在except hash上使用了一组键,对吗? 在写一个问题时它确实更清楚但是,是否有关于何时使用
的经验法则:name
name: value
:name => {values}?
name: [values]
或者只是个人偏好?在这种情况下,我希望我的在线教师保持一致..
一般来说,我对参数语法约定是如何以及何时使用什么(什么类型的参数)非常困惑。 是因为我是从Ruby开始还是我错过了一些约定。
我希望我的问题是可以理解的,并原谅我的英语 - 非母语人士。 我真的很喜欢与RoR相处,但是现在看在线课程有时让我比以前更加困惑,因为如果我自己完成它,我会用完全不同的方式。
答案 0 :(得分:8)
我该怎么知道如何申报这些参数?
你在文档中查找方法,然后阅读它。
解析为此方法的参数是:
:session, :html => {class: "form-horizontal", role: "form"}, url: login_path
我该怎么知道如何申报这些参数?为什么是 :session和:html passend in as keys和url not?是:html符号 一个Hashmap符号?
在ruby中,如果在参数列表的末尾传入一系列键值对,ruby会将它们全部收集到一个哈希中,并将它们作为一个参数传递给该方法。这是一个例子:
def go(x, y)
p x
p y
end
go(:hello, a: 10, b: 20)
--output:--
:hello
{:a=>10, :b=>20}
另一个例子:
def go(x, y)
p x
p y
end
go(
:session,
:html => {class: "form-horizontal", role: "form"},
url: 'xyz'
)
--output:--
:session
{:html=>{:class=>"form-horizontal", :role=>"form"}, :url=>"xyz"}
has_many :users, through: :user_stocks
好的,我得到的第一个参数是:用户和第二个是相同的 如
:through => :user_stocks
正确?
正确。在旧的ruby中,哈希中的键值对是这样写的:
'a' => 'hello'
如果值是符号,则它看起来像这样:
'a' => :hello
如果密钥也是符号,那么你写道:
:a => :hello
在现代红宝石中,如果键是一个符号,你可以写:
a: 'hello'
这是:
的快捷方式:a => 'hello'
如果值也是符号,在现代ruby中它看起来像这样:
a: :hello
这是:
的快捷方式:a => :hello
resources :user_stocks, except: [:show, :edit, :update]
现在我们在except hash上使用了一组键,对吗?
散列名不是except
,但是你是正确的。
关于何时使用
的经验法则/惯例:name # Single symbol argument name: value # A key-value pair in a hash. The key is a symbol. :name => {values}? #A key-value pair in a hash. The value looks like a hash, but the syntax is incorrect. name: [values] #A key-value pair in a hash. The value is your notation for an array.
或者只是个人偏好?在这种情况下,我希望我的在线教师保持一致..
再一次,可以定义一种方法来采用任何类型的参数。由于ruby变量没有类型,因此您必须检查文档。如果某个方法希望您传入一个哈希,其中key:name的值是一个哈希值,那么您需要这样做。另一方面,如果该方法希望您传入一个哈希,其中key:name的值是一个数组,那么您需要这样做。
一般来说,我对参数语法如何很困惑 约定是什么时候使用什么(什么类型的参数)。它只是 因为我从Ruby开始,或者我错过了一些 约定。
Ruby有很多快捷方式,这对初学者来说可能会让人感到困惑。然后是整个String v. Symbol
概念。如果你能理解符号和弦乐之间的实际区别,那么你将领先于游戏。符号就像一个整数。因此,当ruby必须比较符号是否相等时,ruby会比较两个整数,这很快。如果ruby必须比较Strings,那么ruby必须将一个字符串中每个字母的ascii代码与另一个字符串中每个字母的ascii代码进行比较,直到ruby找到差异为止。例如,为了让ruby比较以下两个字符串:
"helloX" v. "helloY"
在之后进行了六次整数比较之前,ruby不会发现差异:
'h' v 'h' => equal
'e' v 'e' => equal
...
...
'X' v 'Y' => not equal
另一方面,如果红宝石进行比较:
:helloX v. :helloY
符号基本上存储为单个整数,如:
341343 v. 134142 => not equal
要比较它们只需要一个整数比较,所以它更快。正如有人肯定会指出的那样,这不是符号实现的方式,但细节并不重要。知道Symbol比较比String比较更快就足够了,至于为什么这是真的,上面的例子足以证明至少有一个实现可以是真的。
答案 1 :(得分:1)
在Ruby哈希中,可以使用“hashrockets”或更新的文字表示法(自Ruby 1.9起):
# hashrockets
{ :foo => "bar" }
# literal
{ foo: "bar" }
他们都做同样的事情。他们使用symbol :foo
作为关键字创建哈希。文字语法为now generally preferered。
如果你有除符号以外的东西作为键(你可以将数字,字符串或任何对象作为键),那么今天只应该使用Hashrockets:
{ 1 => 'a', 2 => 'b' }
# using literals won't work here since it will cast the keys to symbols:
{ 1: 'a', 2: 'b' } # => { :1 => 'a', :2 => 'b' }
由于Ruby是松散类型的哈希,它可以包含任何类型的值:
{ foo: "bar" }
{ foo: [:bar, :baz] }
{ foo: { bar: :baz } }
在Ruby中,方法可以接收序数参数和带选项的哈希:
def foo(bar, hash = {})
@test= hash[:]
end
哈希选项必须位于参数列表中的位置参数之后。
# syntax error
foo(a: 2, "test")
# good
foo("test", a: 2)
传递哈希选项时,您可以隐藏周围的括号:
foo("test", { a: 1, b: 2 })
# same result but nicer to read
foo("test", a: 1, b: 2 )
Ruby 2.0引入了关键字参数,减少了解析选项所需的样板代码量:
def foo(bar, test: nil)
@test= test
end
def foo(bar, test: nil, **kwargs)
@test= test
# all the options except test
puts kwargs.inspect
end
# will raise an error if the test key is not passed
def foo(bar, test:)
@test= test
end
在参数的顺序是自我解释的情况下,后期参数更短且更理想:
class Number
def add(x)
@val += x
end
end
当你有更多具有大量参数的复杂方法时,跟踪顺序可能很棘手:
def book_flight(destination, seats, airline_preference= nil, special_meals= nil)
end
这就是哈希选项进入和闪耀的地方,因为你可以有一个arbirtrary数量的选项,程序不会爆炸,因为你忘了呼叫中的零。