Ruby on Rails和Colons的东西

时间:2017-05-25 18:25:09

标签: ruby-on-rails ruby

我曾经更像是一个业余爱好的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符号吗?

  1. 示例:
  2. 在模型文件中,您声明了这样的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相处,但是现在看在线课程有时让我比以前更加困惑,因为如果我自己完成它,我会用完全不同的方式。

2 个答案:

答案 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)

哈希:hashrockets vs literal

在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数量的选项,程序不会爆炸,因为你忘了呼叫中的零。