класс < < идиома в Ruby

Я презираю, когда вы принудительно присоединяете, используя WHERE. Мне просто не нравится, грязный хак. Правильное соединение ANSI - использовать ON:

SELECT 
    p.Product,
    o.Order
FROM 
    Product p
INNER JOIN
    Order o
ON
    o.OrderID = p.OrderID

Предпочтительно использовать ON при подключении и WHERE для фильтрации результатов. Помните, что ГДЕ - одна из последних вещей, которые вы будете использовать, помимо группировки и порядка, где вы хотите отфильтровать результаты. Таким образом, вы не должны присоединяться к своим таблицам с помощью WHERE, поскольку его трудно прочитать.

SELECT 
    p.Product,
    o.Order
FROM 
    Product p
INNER JOIN
    Order o
ON
    o.OrderID = p.OrderID
WHERE
    o.Category = 'IT'

В конце концов, вы (разработчик), возможно, не будете в будущем, поэтому читаемость и ремонтопригодность будут помогите залить душу, которая должна взять ваш код:).

Когда я вижу, что разработчики используют WHERE для объединения своих таблиц, это обычно указывает на то, что они не знают достаточно T-SQL. Это мое личное мнение.

814
задан Arslan Ali 15 April 2015 в 14:12
поделиться

1 ответ

Во-первых, синтаксис class << foo открывает одноэлементный класс foo (собственный класс). Это позволяет вам специализировать поведение методов, вызываемых для этого конкретного объекта.

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

Теперь, чтобы ответить на вопрос: class << self открывает одноэлементный класс self , так что методы могут быть переопределены для текущего self объект (который внутри тела класса или модуля является самим классом или модулем ). Обычно это используется для определения методов класса / модуля («статических»):

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

Это также можно записать в сокращенном виде:

class String
  def self.value_of obj
    obj.to_s
  end
end

Или даже короче:

def String.value_of obj
  obj.to_s
end

Внутри определения функции self относится к объекту, с которым вызывается функция. В этом случае class << self открывает одноэлементный класс для этого объекта; одно из его применений - реализовать конечный автомат для бедняков:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

Итак, в приведенном выше примере каждый экземпляр StateMachineExample имеет псевдоним process_hook , связанный с process_state_1 , но обратите внимание, как в последнем случае он может переопределить process_hook (только для self , не затрагивая другие экземпляры StateMachineExample ) на process_state_2 . Таким образом, каждый раз, когда вызывающий абонент вызывает метод process (который вызывает переопределяемый process_hook ), поведение изменяется в зависимости от того, в каком состоянии он находится.

878
ответ дан 22 November 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: