0

いくつかの Railscast で、Ryan Bates はこのカスタムの「並べ替え可能な」ヘルパーをいくつかのヘルパー メソッド ( http://railscasts.com/episodes/228-sortable-table-columns ) と組み合わせて使用​​しています。修正版をお見せします。

「ソート可能な」ヘルパー メソッドは次のようになります (独自の目的で変更しましたが、基本的なロジックは同じです)。

def sortable(column, params, title = nil)
  title ||= column.titleize
  direction = column == YearlyDerivative.sort_column(params) && YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc"
  link_to title, params.merge(:sort => column, :direction => direction)
end

上記の次の行に困惑し、圧倒されますdirection = column == YearlyDerivative.sort_column(params) && YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc"

この 1 行に従うために必要な構文上の代数的な規則 (div/mult-first、加算/サブセカンド規則などを考えさせられる) をすべて知っていたとしても、必要な Ruby の知識をまだ持っていない可能性があります。 (「真実」演算子)ここで何が起こっているのかを完全に理解するために。私が求めているのはウォークスルーです。まず第一に、私のヒューズは、最初からdirection = column == ...ちょっと飛んでいます。しかし、後で別の等値演算子と三項演算子が介入すると、すべての理解が失われます。

ご参考までに、sort_column と sort_direction は YearlyDerivative クラス メソッドです (実際に存在する必要はありません。別の場所から呼び出す必要があっただけなので、うまくいきました)。

def self.sort_column(p)
  YearlyDerivative.column_names.include?(p[:sort]) ? p[:sort] : "revenue_usd_mil_derivative"
end

def self.sort_direction(p)
  %w[asc desc].include?(p[:direction]) ? p[:direction] : "asc"
end

その1 行( direction = column == YearlyDerivative.sort_column(params) && YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc") には、1 つの代入、2 つの等値演算子、1 つの && 演算子、および 3 項演算子が含まれています。もちろん外部呼び出しメソッドも含めて3つの三項演算子を使っているのですが、理解に苦しむことはありません。

お待ち頂きまして、ありがとうございます。これを理解することで、私や他の SO 読者/検索者が予期しないプログラミングの洞察を得ることができることを願っています。

4

4 に答える 4

1

私の考えでは、これはいくつかのロジックを 1 行に統合することで賢くしようとする試みの 1 つであり、実際に行うべきではありませんでした。本当の最終結果は、コードが何をしているかを理解するときにメンテナーが遅くなるため、混乱を招き、コードの保守が難しくなります。

direction = column == YearlyDerivative.sort_column(params) && YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc".

それを分解する:

if (
  (column == YearlyDerivative.sort_column(params)) &&
  (YearlyDerivative.sort_direction(params) == "desc")
)
  direction = "asc" 
else
  direction = "desc"
end

Ruby では、読みやすさと分かりやすさを維持しながら、もう少し単純化することもできます。

direction = if (
              (column == YearlyDerivative.sort_column(params)) &&
              (YearlyDerivative.sort_direction(params) == "desc")
            )
              "asc" 
            else
              "desc"
            end

次のように書くこともできます。これは、Ruby に関する限り実質的に 1 行ですが、かっこを使用してロジックをチャンクに分割しているため、元の 1 行のコードよりも理解しやすいままです。

direction = (
  (column == YearlyDerivative.sort_column(params)) &&
  (YearlyDerivative.sort_direction(params) == "desc")
) ? "asc" : "desc"
于 2013-03-10T04:19:39.823 に答える
0

これがステップバイステップです:

  1. direction次のステートメントの結果に設定
  2. column等しいかどうかYearlyDerivative.sort_direction(params)
  3. (2) が true の場合、残りの行を返します
  4. YearlyDerivative.sort_direction(params) == "desc"true の場合は return "asc"、elseを返します"desc"

または、この(ほぼ)同等のコード:

if(column == YearlyDerivative.sort_direction(params))
  if(YearlyDerivative.sort_direction(params) == "desc")
    direction = "asc"
  else
    direction = "desc"
  end
else
  false
end
于 2013-03-10T03:50:49.750 に答える
0

メソッドにカプセル化された三項演算子を使用して呼び出しキューを理解するのに問題はないので、ワンライナーを逆アセンブルしてからアセンブルし直すことをお勧めします。

def func1
  column == YearlyDerivative.sort_column(params)
end
def func2 
  YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc"
end
direction = func1 && func2

それでは、組み立ててみましょう。

#           ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓ func1 ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓    ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓ func2 ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓ 
direction = (column == YearlyDerivative.sort_column(params)) && (YearlyDerivative.sort_direction(params) == "desc" ? "asc" : "desc")

上記の中括弧は、演算子の優先順位表に従って簡単に省略できます。

さらに、合計ワンライナーに敬意を表して関数を削除できるようになりました。

direction = column == (YearlyDerivative.column_names.include?(p[:sort]) ? p[:sort] : "revenue_usd_mil_derivative") && %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc") == "desc" ? "asc" : "desc"

それが役立つことを願っています。

于 2013-03-10T04:21:25.380 に答える
0

実際にコードを次のように切り替えました

def sortable(column, params, title = nil)
  title ||= column.titleize
  if YearlyDerivative.test_column(params) && YearlyDerivative.sort_direction(params) == "asc"
    direction = "desc"
  else
    direction = "asc"
  end
  link_to title, params.merge(:sort => column, :direction => direction)
end

sort_column メソッドが test_column メソッドに変更されていることに注意してください。これはより論理的だと思います。

def self.test_column(p)
  YearlyDerivative.column_names.include?(p[:sort]) ? true : false
end

sort_column メソッドは、「sort」クラス メソッド (下記) で引き続き使用されます。

def self.sort(params); p = params
  order(sort_column(p) + " " + sort_direction(p))
end

** 元の sortable ヘルパー メソッドの 2 部構成の条件付き要件の最初の部分が役に立たなかったようです。&& 演算子に関する限り、true が返されました。

def sort_column(p)
  ["a", "b", "c"].include?(p[:sort]) ? p[:sort] : "is it true or false?"
end
bad_params = {:sort => "d"}
x = true
if sort_column(bad_params) && x
  puts "hmm"
else; puts "it implied false"
end
#=> "hmm"

上記の ruby​​ の性質のテストにより、test_column メソッドを作成することになりました。

于 2013-03-10T05:14:34.963 に答える