![](/img/trans.png)
[英]Ruby on Rails and angularJS: Can someone explain the usage and syntax pls
[英]Explain Iterator Syntax on Ruby on Rails
我開始學習Ruby on Rails並發現自己對語法感到困惑,所以我不得不閱讀一些Ruby語法。 我從http://www.cs.auckland.ac.nz/references/ruby/doc_bundle/Manual/man-1.4/syntax.html學習了語法:
method_call do [`|' expr...`|'] expr...end
他們稱之為迭代器。 我理解一個迭代器運行循環,但我不明白我應該如何閱讀這個或者在這個語法中發生了什么。 我一直在RoR的截屏視頻中看到它並且這些詞語有意義,但我實際上不知道發生了什么。 誰有人向我解釋這個?
編輯:示例
respond_to do |format|
format.json
format.xml { render :xml => @posts }
end
方法可以采用稱為“塊”的構造。 這些是傳遞給方法的匿名方法。
另一種語法是:
method_call { |var| do_something(var) }
基本上,您是說對於迭代中的每個項目,將其命名為“var”並對該項執行某些操作。 該方法只是調用您傳入的塊,因為它會“生成”項目。
這有幫助嗎?
編輯:在你的例子中,他們以一種有趣的方式使用迭代器模式...可能只將一個format
對象傳遞到你的塊中,這樣你就可以告訴它要處理哪些格式,以及當你看到它時要做什么。
換句話說,他們正在使用該模式創建各種DSL,以便您配置響應的內容。
在迭代器的情況下,將它們想象成Java中的接口:您可以在Ruby中執行for循環,但是您可能想要迭代的所有對象(應該)實現占用塊的“each”方法(即一個閉包,一個匿名函數)。
塊在Ruby中被遍地使用。 想象一下你有這個數組:
[1, 2, 3, 4, 5, 6].each do |i| puts i.to_s end
在這里,您正在創建數組,然后您在其上調用'each'方法。 你把塊傳遞給它。 您可以將其分開,如下所示:
arr = [1, 2, 3, 4, 5, 6]
string_printer = lambda do |i| puts i.to_s end
arr.each(&string_printer)
這種接口在其他方面實現:Hash集合允許您遍歷鍵值對:
{:name => "Tom", :gender => :male}.each do |key, value| puts key end
do..end可以替換為大括號,如下所示:
[1, 2, 3, 4, 5, 6].each {|i| puts i.to_s }
由於Ruby使用的函數式編程,這種迭代成為可能:如果要創建一個需要迭代某些東西的類,您還可以實現每個方法。 考慮:
class AddressBook
attr_accessor :addresses
def each(&block)
@addresses.each {|i| yield i }
end
end
各種類通過這種塊模式實現了有趣的功能:例如,查看String的each_line和each_byte方法。
method_call do [`|' expr...`|'] expr...end
不僅限於迭代函數。
在ruby中,任何方法都可以將塊作為參數。 然后可以通過該方法調用該塊。 在迭代器的情況下,該方法看起來像這樣:
def iter
for i in [:x,:y,:z]
yield i
end
end
如果你用一個塊調用iter
,它將循環遍歷[:x, :y, :z]
並將它們中的每一個放到塊中,然后可以執行任何操作。 例如打印出來:
iter { |z| puts z }
您還可以使用它來隱藏初始化和清理步驟,例如打開和關閉文件。 例如File.open
。 File.open,如果它是在純ruby中實現的(它在C中表示性能)會做這樣的事情。
def File.open filename, opts
f = File.new filename, opts
yield f
f.close
end
這就是你可以使用的原因
File.open 'foobar', 'w' do |f|
f.write 'awesome'
end
respond_to
是類似的。 它的工作原理如下:(查看這里的實際實現)
def respond_to
responder = Responder.new(self)
block.call(responder)
responder.respond
end
它創建一個響應器對象,其中包含html
方法,它們會將塊傳遞給您。 事實證明這非常方便,因為它可以讓你做以下事情:
def action
@foo = Foo.new params[:foo]
respond_to do |format|
if @foo.save
format.html { redirect_to foo_path @foo }
format.xml { render :xml => @foo.to_xml }
else
flash[:error] = "Foo could not be saved!"
format.html { render :new }
format.xml { render :xml => {:errors => @foo.errors }.to_xml}
end
end
end
看看我如何改變依賴於塊內保存的行為? 沒有它,這樣做會更煩人。
<function> do |<temp variable>|
<code to operate on temp variable>
end
這將創建一個臨時匿名函數,該函數將項接受到臨時變量中,然后讓事物對該項進行操作。 匿名函數被傳遞給指定的原始<function>
,以對該函數產生的項進行操作。
你看到的是一段代碼,當你第一次看到它時,語法有點尷尬。
所以,基本上,對於迭代器,你有一個可以重復的“東西”,它會收到一個塊來知道該怎么做。
例如, Range類有一個名為“each”的方法,它接收要在該范圍內的每個元素上執行的代碼塊。
假設您要打印它:
range = 1..10 #range literal
range.each {|i|
puts i
}
代碼: {|i| puts i}
{|i| puts i}
是一個塊,它表示當這個范圍迭代每個元素時該怎么做。 替代語法是您發布的語法:
range.each do |i|
puts i
end
這些塊與迭代器一起使用,但它們不限於“迭代”代碼,您可以在其他場景中使用它們,例如:
class Person
def initialize( with_name )
@name = with_name
end
# executes a block
def greet
yield @name #passes private attribute name to the block
end
end
p = Person.new "Oscar"
p.greet { |n|
puts "Name length = #{n.length}"
puts "Hello, #{n}"
}
打印:
Name length = 5
Hello, Oscar
因此,使用塊而不是使用具有固定行為的greet
方法,讓開發人員指定要做什么,這對迭代器非常有幫助,但是你只是見證了不是唯一的地方。 在您的情況下,該塊允許您指定在respond_to
方法中執行的操作。
你正在閱讀的文件很古老 - 實際上是史前的。 如果網頁可能會聚集灰塵,那么會有一層厚厚的網頁。
在ruby-lang網站上試用參考資料。 此外, Programming Ruby (pickaxe)書籍是必不可少的參考書。
我認為你可以稱之為迭代器,因為通常會多次調用塊函數。 如:
5.times do |i|
puts "#{i} "
end
“在幕后”,進行了以下步驟:
5
的方法times
,傳遞代碼puts "#{i} "
放入Proc
對象實例中。 times
方法中,此代碼在循環內部調用,將當前索引作為參數傳遞。 這就是times
可能看起來像( 它在C,實際上 ): class Fixnum
def times_2(&block) # Specifying &block as a parameter is optional
return self unless block_given?
i = 0
while(i < self) do
yield i # Here the proc instance "block" is called
i += 1
end
return self
end
end
請注意,范圍(即局部變量等)被復制到塊函數中:
x = ' '
5.times do { |i| puts "#{i}" + x }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.