Day3 讀書筆記&心得體會

一、讀書筆記
2.6 Block和迭代器

  • 本節(jié)簡單描述Ruby的一個獨特特性,Block,一種可以和方法調用相關聯(lián)的代碼塊,幾乎和參數(shù)一樣,這是一個不可思議的強大的特性。一位評論家說:這個特性是相當有趣和重要,如果以前沒有注意到,從現(xiàn)在開始你應該注意了。

  • 可以用Block實現(xiàn)回調(但它比Java的匿名內部(anonymous inner)類更簡單),傳遞一組代碼(但它遠比C的函數(shù)指針更靈活),以及實現(xiàn)迭代器。

  • Block 只是花括號或者do...end之間的一組代碼

{ puts "Hello" }
do
    club.enroll(person)
    person.socialize
end

為什么有兩種分解符呢?部分是有人覺得有時候用一種分解符比另外一種感覺更自然。另外一部分原因是它們有不同的優(yōu)先級:花括號比do/end綁定的更緊密些,在本書中,我們嘗試遵循正在成為Ruby標準的一個約定俗成,單行block用花括號,多行block用do/end。

  • 一旦創(chuàng)建了block,就可以與方法的調用相關聯(lián)。把block的開始放在含有方法調用的源碼行的結尾處,就可以實現(xiàn)關聯(lián)。比如,在下面的代碼中,含有puts "Hi"的block與greet方法的調用相關聯(lián)。

  • greet { puts "Hi" }
    如果方法有參數(shù),它們出現(xiàn)在block之前。

verbose_greet("Dave", "loyal customer")  { puts "Hi" }

然后使用Ruby的yield語句,方法可以一次或多次地調用(invoke)相關聯(lián)的block??梢园褃ield想象成比如方法調用,它調用含有yield語句的方法所關聯(lián)的block。

  • 下面的例子顯示了如何使用yield語句,定義了一個方法,它會調用yield兩次,然后調用這個方法,把block放在同一行,在方法調用之后(并在方法的所有參數(shù)之后)。
def call_block
    puts "Start of method"
    yield
    yield
    puts "End of method"
end

輸出結果:

Start of method
In the block
In the block
End of method

看看(puts "In the block")block中的代碼塊如何被執(zhí)行兩次,每次調用yield時,代碼都會被執(zhí)行。

  • 可以提供參數(shù)給對yield的調用:參數(shù)會傳遞到block中,在block中,豎線(|)之間給出參數(shù)名來接受這些來自yield的參數(shù)。
def call_block
    yield("hello", 99)
end
call_block { |str,  num| ... }

在Ruby庫中大量使用了block來實現(xiàn)迭代器:迭代器是從某種收集(collection)如數(shù)組中連續(xù)返回元素的方法。

animals = %w( ant bee cat dog elk )  # 創(chuàng)建一個數(shù)組
animals.each { |animal| puts animal }  # 迭代它的內容
輸出結果:
ant
bee
cat
dog
elk
  • 讓我們看一下如何實現(xiàn)應用在前面例子中的Array類中的each迭代器。each迭代器循環(huán)處理數(shù)組中的元素,對每個元素調用yield。在偽碼中,它可能寫成:
    在Array類中... ...
def each
    for each element  # 無效的Ruby語句 
      yield(element)  
    end
end
  • 許多內建于C和Java等語言的循環(huán)結構在Ruby中只是方法調用,這些方法會零次或多次調用相關聯(lián)的block。
['cat', 'dog', 'horse'].each { |name| print name, " " }
5.times { print "*" }
3.upto(6) { |i| print i }
('a'..'e').each { |char| print char }

輸出結果:

cat dog horse *****3456abcde

上面的代碼要求對象5 五次調用block;然后要求對象3 調用一個block,并傳入一個連續(xù)的值,直到這個值到達6為止。最后對a到e的字符區(qū)間(range),使用each方法調用block。

2.7 讀/寫文件

  • Ruby有一個完備的I/O庫,但是本書的大多數(shù)例子只使用其中一些簡單的方法,已經碰到了兩個用來輸出的方法。puts輸出參數(shù),并在每個參數(shù)后面添加回車換行符。print也輸出它的參數(shù),但沒有添加換行符。它們都可以用來向任何I/O對象進行輸出,但在默認情況下,它們輸出到標準輸出。

  • 另一個常用的輸出方法是printf,它在一個格式化字符串的控制下打印出它的參數(shù)(就像C或Perl中的prinf)。

printf("Number: %5.2f, \nString: %s\n", 1.23, "hello")

輸出結果:
Number:1.23,
String:"hello"
在這個例子中,"Number: %5.2f, \nString: %\n"格式化字符串,告訴printf替換一個浮點數(shù)(最多允許5個字符串, 并且2個在小數(shù)點后面)和一個字符串。注意到回車換行符(\n)嵌入到格式化中:回車換行符把輸出移動到下一行。

  • 有許多方式可以把輸入讀到程序中:回車換行符把輸出移動到下一行。
  • 有許多方式可以把輸入讀到程序中,最傳統(tǒng)的方式是使用gets函數(shù),它從程序的標準輸入流中讀取下一行。
line = gets
print line

二、心得體會
今天完成了什么?
1.聽劍爸講解app.rb
2.讀了《Programming Ruby》的第2.6-8節(jié)
3.試著解釋app.rb昨天剩余的部分
4.跟小白探討網站的模型、視圖等等之間的關系

今天學到了什么?

  • try 如果接收對象是零對象或NilClass,則NoMethodError異常將不會被引發(fā),否則將返回nil。
  • distinct: true
  • to_s 用于將對象顯示為字符串,通常是使用put的結果;注意,甚至可以通過覆蓋檢查,來覆蓋顯示對象的內容。
  • to_h 返回此參數(shù)的安全哈希表示,并刪除所有未提交的鍵。
  • awesome_print 可以全面打印Ruby對象,舉個例子:
ap Group::Post
  • slim模板 致力于減少視圖語法代碼,方便、快捷
    舉個例子:
ruby:
  fields = {
    name: { edit: true },
    parent_id: { edit: -> (f) { f.grouped_collection_select :parent_id, [ [ '一級', [ model.root ] ],...class: 'width-100 Chosen' } },
    children: {},
    orders: {},
    words: {},
  }
= render 'admin/.../form', fields: fields

代碼理解:

  def ix
    @records = (@records || model)
      .ransack(params[:q]).result(distinct: true) # 搜索那些不重復的記錄
      .order([ params[:order].to_s.match(/\A(\w+)\s(asc|desc)\Z/).try(:[], 1..2) || %w[ id desc ] ].to_h) # 排序
      .page(params[:page]).per(params[:per]) #分頁

    respond_to do |format| #導出格式
      format.html
     ...
    end
  end

  def rt
    return redirect_to @url if @url = current_user.admin_operator.try(:url).presence #判斷是否有登錄和操作權限
    render html: '', layout: true
  end

  private

  def rd_with_record
    respond_to do |format|
      format.html do
       ....
      end
      format.json { render json: @record.as_json(model.admin_json_options || model.json_options || { only: %i[ id ] }), status: request.get? ? :ok : !@saved ? :unprocessable_entity : params[:action] == 'create' ? :created : :accepted }
    end
  end

  def ce_log
    return if request.get? && !(params[:controller] == 'admin/bag/orders' && params[:action].starts_with?('stats_'))
    Admin::Log.create({
      operator: current_user.admin_operator, # 操作權限
      resource: params[:controller].remove(/^admin\//).singularize, # 資源
      action: params[:action], # 動作
      paramid: params[:id], # id
    })
  end

  def rs_data # 導出數(shù)據(jù)
    fields = [ :id ] + (model.export_fields || []) + [ :created_at, :updated_at ].find_all { |field| model.column_for_attribute(field) } # 選擇要導出的欄位
    header = fields.map { |field| model.human_attribute_name(model.reflections[field.to_s].try(:foreign_key) || field) } # 導出的欄位標題
    body = @records.map do |record| # 主要內容
      fields.map do |field|
        next I18n.t("activerecord.enums.#{model.name.underscore}.#{field}").with_indifferent_access[record.send(field)] if model.defined_enums.with_indifferent_access[field]
        case value = field.to_s.split('.').inject(record) { |object, method| object.try(method) }
        when true
          '?'
        when false
          '?'
       ....
        else
          value
        end
      end
    end
    [ header ] + body
  end

end

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一、讀書筆記3.4 剩余部分當對象需要訪問同類的其他對象的內部狀態(tài)時,使用保護訪問(protected acces...
    柳輝閱讀 446評論 0 0
  • 一、心得體會1、今天完成了什么? 20頁鎬頭書 10個controller 回顧以前什么是block?為什么要有b...
    柳輝閱讀 552評論 0 0
  • 一、讀書筆記回顧昨天的收獲:什么是block、proc? block和proc是兩種不同的東西, block有形無...
    柳輝閱讀 440評論 0 0
  • 一、心得體會1、今天完成了什么? 今天看了20頁的鎬頭書(139-160) 看了10個controller 2、今...
    柳輝閱讀 411評論 0 0
  • 一、心得體會1、完成了什么? 看了20頁鎬頭書 看了10個controller 2、收獲了什么? sub與gsub...
    柳輝閱讀 319評論 0 0

友情鏈接更多精彩內容