簡體   English   中英

[X,Y,Z] .each {| m |的區別是什么? 包括m}並包括X,Y,Z?

[英]What is the difference between [X,Y,Z].each {|m| include m} and include X, Y, Z?

注意這最初是作為一個關於404錯誤的問題開始的,但是現在這是一個問題,為什么我應用的補丁會產生影響。

如何獲得緩存操作以在所有引發ActiveRecord :: RecordNotFound異常的請求上返回404,而不僅僅是第一個請求?

例如,如果你啟動一個空的rails項目,添加一個產品模型和控制器,設置你的database.yml,在production.rb中設置你的緩存后端,rake db:migrate,然后開始生產並點擊該網站獲取非現有對象,例如http:// localhost:3000 / product / show / 1234

class ProductController < ApplicationController

  caches_action :show

  def show
    @product = Product.find(params[:id])
    render :text => "asdf"
  end

end

第一次點擊頁面時,它會按預期返回404頁面。 但是,對該URL的每次后續匹配都會返回一個200 OK的空白頁面。 你怎么得到它每次返回404?

以下是CURL請求,后跟日志

~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 404 Not Found
Connection: close
Date: Mon, 20 Apr 2009 22:49:18 GMT
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 14097

~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 200 OK
Connection: close
Date: Mon, 20 Apr 2009 22:49:19 GMT
X-Runtime: 6
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 0

第二個反應顯然是錯誤的。

以下是2個請求的日志副本:

Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:24) [GET]
  Parameters: {"id"=>"1234"}

ActiveRecord::RecordNotFound (Couldn't find Product with ID=1234):
  app/controllers/product_controller.rb:6:in `show'

Rendering rescues/layout (not_found)


Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:30) [GET]
  Parameters: {"id"=>"1234"}
Filter chain halted as [#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>] rendered_or_redirected.
Filter chain halted as [#<ActionController::Filters::AroundFilter:0x23e3580 @kind=:filter, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>, @identifier=nil>] did_not_yield.
Completed in 12ms (View: 0, DB: 0) | 200 OK [http://0.0.0.0/product/show/1234]

實際上,如果你將緩存的操作從緩存中拉出來,那里就會有一些空垃圾。

cache.fetch("views/0.0.0.0:3000/product/show/1234")
=> ["", nil, [], []]

我在這做錯了什么?

編輯

我已經確認Rails 2.1.2和2.2.2沒有表現出這種行為,但2.3.2確實如此。 (即舊版本不會將空響應存儲到緩存中,並且它們確實會為后續請求拋出404)

我在測試邊緣Rails時遇到問題,因為在啟動服務器時加載它會導致以下錯誤:foobar / vendor / rails / activesupport / lib / active_support / dependencies.rb:440:in`load_missing_constant':uninitialized constant ActionController ::故障安全(NameError)

我已經對2-3穩定分支375e8976e3的當前負責人進行了測試,它也表現出這種行為。

編輯#2我試圖跟蹤Rails代碼庫中發生更改的時間,以確定它是否是故意的。 似乎這個看似無害的提交是bug開始的地方。

以下是二分的細節,其中404表示期望的行為,200表示不期望的行為。

2-3-stable branch
    375e8976e3 - 200
    b1c989f28d - 200
    beca1f2e15 - 200
    f1fff0a48  - 200
    f1e20ce9a7 - 200
    a5004573d8 - 200
    2e1132fad8 - 200 - the difference seems to start at this commit
    c69d8c043f - 404
    d961592886 - 404
    276ec16007 - 404
    0efec6452  - 404
    13c6c3cfc5 - 404
    fb2325e35  - 404

2-2 stable
    3cb89257b4 - 404

這是一個反轉更改的補丁,當應用於標記v2.3.2.1,即dc88847e5ce392eed210b97525c14fca55852867時,修復了該問題。 然而,我不夠聰明,不知道為什么這個看似微不足道的變化實際上會有所作為! 也許比我聰明的人可以對這種情況有所了解?

diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 0facf70..0790807 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -1403,12 +1403,9 @@ module ActionController #:nodoc:
   end

   Base.class_eval do
-    [ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
-      Cookies, Caching, Verification, Streaming, SessionManagement,
-      HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
-      RecordIdentifier, RequestForgeryProtection, Translation
-    ].each do |mod|
-      include mod
-    end
+    include Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers
+    include Cookies, Caching, Verification, Streaming, SessionManagement
+    include HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods
+    include RecordIdentifier, RequestForgeryProtection, Translation
   end
 end

編輯#3補丁似乎也修復了上面顯示的相關錯誤,其中“在XYms中完成(DB:Z)| 404找不到[ http://0.0.0.0/product/1234] ”沒有顯示在日志。

編輯#4上面的補丁破壞了ActionPack中的其他內容,因此我深入研究並生成了一個不會導致附帶損害的問題。 補丁和任何后續更新將在軌道燈塔

似乎include(X, Y, Z)實際上以與include X; include Y; include Z不同的順序操作include X; include Y; include Z include X; include Y; include Z include X; include Y; include Z

下面我粘貼了在Ruby 1.8.6中實現Module#include方法的C代碼。

static VALUE
rb_mod_include(argc, argv, module)
    int argc;
    VALUE *argv;
    VALUE module;
{
    int i;

    for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE);
    while (argc--) {
      rb_funcall(argv[argc], rb_intern("append_features"), 1, module);
      rb_funcall(argv[argc], rb_intern("included"), 1, module);
    }
    return module;
}

即使你不熟悉Ruby的C內部,很明顯這個函數有一個for循環向上迭代來檢查所有參數的類型是否為T_MODULE,然后使用while循環向下迭代以實際包含模塊 - 因此, include(X, Y, Z)的模塊實際上將包括在Z, Y, X的順序中。 我還沒有瀏覽過所有相關的Rails模塊,但我想有一些依賴於順序的東西,一旦切換包含順序就開始失敗了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM