Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl's __SUB__ analogue for Ruby

Tags:

ruby

lambda

In Perl we can use __SUB__ to get the reference to the current subroutine. Is there analogue for Ruby?

For example let's write an anonymous factorial subroutine in Perl:

my $fact = sub {
    $_[0] > 1 ? $_[0] * __SUB__->($_[0] - 1) : 1;
};

In Ruby I'd create a named method first and then convert it to lambda:

def factorial(n) 
  n > 1 ? n * factorial(n - 1) : 1
end

fact = method(:factorial).to_proc

I feel it is not the best way to write recursive lambdas. Did I miss something?

like image 627
user2422869 Avatar asked Nov 02 '22 04:11

user2422869


1 Answers

I don't think Ruby provides any built-in utilities that will help you perform recursion without first naming the function; however, you could use the Y-combinator in Ruby to do so:

def y_combinator(&generator)
  proc { |x|
    proc { |*args| generator.call(x.call(x)).call(*args) }
  }.call(proc { |x|
    proc { |*args| generator.call(x.call(x)).call(*args) }
  })
end

factorial = y_combinator do |callback|
  proc { |n| n > 1 ? n * callback.call(n - 1) : 1 }
end

factorial.call(5) # => 120
like image 153
maerics Avatar answered Nov 09 '22 13:11

maerics