Class: Proc

Inherits:
Object
  • Object
show all
Defined in:
lib/ludy/proc/bind.rb,
lib/ludy/proc/chain.rb,
lib/ludy/proc/curry.rb,
lib/ludy/proc/compose.rb

Instance Method Summary collapse

Instance Method Details

#__curry__(*pre) ⇒ Object

:nodoc:



5
6
7
# File 'lib/ludy/proc/curry.rb', line 5

def __curry__ *pre # :nodoc:
  lambda{ |*post| self[*(pre + post)] }
end

#bind(*args) ⇒ Object

C++ TR1 style bind use _#n for placeholders

_1 => 1st arg
_2 => 2nd arg
...and so on


8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/ludy/proc/bind.rb', line 8

def bind *args
  lambda{ |*new_args|
    self[*(args.map{ |arg|
      if (arg.kind_of? Symbol) && arg.to_s =~ /^_(\d+)$/
        # is placeholder
        new_args[$1.to_i-1]
      else
        # is not placeholder
        arg
      end
    } + new_args).first(self.arity)]
  }
end

#chain(*procs, &block) ⇒ Object

TODO: missing traversal of chain create a chain of proc. whenever you call the chain, each proc would be called. the return value would be all the results saved orderly in a array.



7
8
9
10
11
12
13
14
15
16
# File 'lib/ludy/proc/chain.rb', line 7

def chain *procs, &block
  procs << block if block
  lambda{ |*args|
    result = []
    ([self] + procs).each{ |i|
      result += [i[*args]].flatten
    }
    result
  }
end

#compose(*procs, &block) ⇒ Object

function coposition i.e., f compose g => f of g => f (g args)



5
6
7
8
# File 'lib/ludy/proc/compose.rb', line 5

def compose *procs, &block
  procs << block if block
  lambda{ |*args| ([self] + procs).reverse.inject(args){ |val, fun| fun[*val] } }
end

#curryObject

make the caller be a curried function

lambda{|a,b,c| [a,b,c]}.curry[1][2][3]
=> [1,2,3]


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ludy/proc/curry.rb', line 12

def curry
  class << self
    alias_method :__call__, :call
    def call *args, &block # :nodoc:
      if self.arity == -1
        begin # let's try if arguments are ready
          # is there any better way to determine this?
          # it's hard to detect correct arity value when
          # Symbol#to_proc happened
          # e.g., :message_that_you_never_know.to_proc.arity => ?
          # i'd tried put hacks in Symbol#to_proc, but it's
          # difficult to implement in correct way
          # i would try it again in other day
          self.public_send :__call__, *args, &block
        rescue ArgumentError # oops, let's curry it
          method(:call).to_proc.public_send :__curry__, *args
        end
      elsif args.size == self.arity
        self.public_send :__call__, *args, &block
      else
        method(:call).to_proc.public_send :__curry__, *args
      end
    end
    alias_method :[], :call
  end
  self
end