условное объединение в цепочку в рубине

Как упомянуто, чисто функциональные языки по сути parallelizable. Однако императивные языки намного более интуитивны для многих людей, и мы глубоко укреплены в обязательном унаследованном коде. Основная проблема - то, что чистые функциональные языки выражают побочные эффекты явно, в то время как побочные эффекты выражаются неявно на императивных языках по приказу операторов.

я полагаю, что методы для декларативного выражения побочных эффектов (например, в объектно-ориентированной платформе) позволят компиляторам разлагать исполняемые операторы на свои функциональные отношения. Это должно тогда позволить коду быть автоматически параллелизированным почти таким же способом, которым был бы чистый функциональный код.

, Конечно, так же, как сегодня все еще желательно записать определенный критический по отношению к производительности код в ассемблере, это все еще будет необходимо для критического по отношению к производительности записи, явно параллельны коду завтра. Однако методы, такие как я обрисовал в общих чертах, должен помочь автоматически использовать в своих интересах manycore архитектуру с минимальным усилием, израсходованным разработчиком.

20
задан DanSingerman 25 November 2009 в 14:18
поделиться

5 ответов

Вы можете поместить свои методы в массив, а затем выполнить все в этом массиве

l= []
l << :method_a if a
l << :method_b if b
l << :method_c if c

l.inject(object) { |obj, method| obj.send(method) }

Object # send выполняет метод с заданным именем. Enumerable # inject выполняет итерацию по массиву, передавая блоку последнее возвращенное значение и текущий элемент массива.

Если вы хотите, чтобы ваш метод принимал аргументы, вы также можете сделать это следующим образом

l= []
l << [:method_a, arg_a1, arg_a2] if a
l << [:method_b, arg_b1] if b
l << [:method_c, arg_c1, arg_c2, arg_c3] if c

l.inject(object) { |obj, method_and_args| obj.send(*method_and_args) }
30
ответ дан 29 November 2019 в 23:20
поделиться

Вы можете использовать tap :

my_object.tap{|o|o.method_a if a}.tap{|o|o.method_b if b}.tap{|o|o.method_c if c}
10
ответ дан 29 November 2019 в 23:20
поделиться

Хотя метод впрыска вполне допустим, такое использование Enumerable сбивает людей с толку и страдает от ограничений, связанных с невозможностью передавать произвольные параметры.

Подобный шаблон может быть лучше для этого приложения:

object = my_object

if (a)
  object = object.method_a(:arg_a)
end

if (b)
  object = object.method_b
end

if (c)
  object = object.method_c('arg_c1', 'arg_c2')
end

Я обнаружил, что это полезно при использовании named объемы. Например:

scope = Person

if (params[:filter_by_age])
  scope = scope.in_age_group(params[:filter_by_age])
end

if (params[:country])
  scope = scope.in_country(params[:country])
end

# Usually a will_paginate-type call is made here, too
@people = scope.all
3
ответ дан 29 November 2019 в 23:20
поделиться

Я использую этот шаблон:

class A
  def some_method_because_of_a
     ...
     return self
  end

  def some_method_because_of_b
     ...
     return self
  end
end

a = A.new
a.some_method_because_of_a().some_method_because_of_b()
1
ответ дан 29 November 2019 в 23:20
поделиться

Возможно, ваша ситуация сложнее, но почему бы и нет:

my_object.method_a if a
my_object.method_b if b
my_object.method_c if c
1
ответ дан 29 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

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