Ruby функционирует по сравнению с методами

Я немного опоздал с игрой, но я могу предложить вклад, который может считаться более элегантным в нескольких смыслах:

def partitions(n, m = None):
  """Partition n with a maximum part size of m. Yield non-increasing
  lists in decreasing lexicographic order. The default for m is
  effectively n, so the second argument is not needed to create the
  generator unless you do want to limit part sizes.
  """
  if m is None or m >= n: yield [n]
  for f in range(n-1 if (m is None or m >= n) else m, 0, -1):
    for p in partitions(n-f, f): yield [f] + p

Только 3 строки кода. Выдает их в лексикографическом порядке. Опционально позволяет наложение максимального размера детали.

У меня также есть вариация описанного выше для разделов с заданным количеством частей:

def sized_partitions(n, k, m = None):
  """Partition n into k parts with a max part of m.
  Yield non-increasing lists.  m not needed to create generator.
  """
  if k == 1:
    yield [n]
    return
  for f in range(n-k+1 if (m is None or m > n-k+1) else m, (n-1)//k, -1): 
    for p in sized_partitions(n-f, k-1, f): yield [f] + p

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

def partitions(sum, max_val=100000, max_len=100000):
    """ generator of partitions of sum with limits on values and length """
    # Yields lists in decreasing lexicographical order. 
    # To get any length, omit 3rd arg.
    # To get all partitions, omit 2nd and 3rd args. 

    if sum <= max_val:       # Can start with a singleton.
        yield [sum]

    # Must have first*max_len >= sum; i.e. first >= sum/max_len.
    for first in range(min(sum-1, max_val), max(0, (sum-1)//max_len), -1):
        for p in partitions(sum-first, first, max_len-1):
            yield [first]+p
27
задан Joshua Ball 29 May 2009 в 22:40
поделиться

3 ответа

лямбда в Ruby являются объектами класса Proc. Объекты Proc не принадлежат никакому объекту. Они вызываются без привязки их к объекту.

Методы - это объекты либо класса Method , либо UnboundMethod , в зависимости от того, связаны они или нет. См. Объяснение здесь . Несвязанные методы нельзя вызывать, пока они не будут привязаны к объекту.

lambda{|x| x}.class      # => Proc
lambda{|x| x}.call(123)  # => 123

class Foo
  def bar(baz)
    baz
  end
end

puts Foo.new.method(:bar).class     # => Method
puts Foo.new.method(:bar).call(123) # => 123

puts Foo.instance_method(:bar).class     # => UnboundMethod
puts Foo.instance_method(:bar).call(123) # => throws an exception

Вы можете привязать UnboundMethod к объекту, а затем вызвать его. Но вы вообще не можете привязать Proc к объекту. Однако объекты Proc могут захватывать локальные переменные в окружающей области видимости, становясь замыканиями.

21
ответ дан 28 November 2019 в 05:41
поделиться

Procs и lambdas являются объектами сами по себе, с методом call , который фактически вызывает блок, связанный с процедурой (или lambda). Однако Ruby предоставляет некоторый синтаксический сахар для их вызова без явного вызова call .

5
ответ дан 28 November 2019 в 05:41
поделиться

Я думаю, что разница между методами и функцией первого порядка т.е. функции, которые можно передавать как значения.

5
ответ дан 28 November 2019 в 05:41
поделиться
Другие вопросы по тегам:

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