Class: Proc

Inherits:
Object show all
Defined in:
lib/more/facets/curry.rb,
lib/core/facets/proc/bind.rb,
lib/core/facets/conversion.rb,
lib/more/facets/openobject.rb,
lib/core/facets/proc/compose.rb

Instance Method Summary collapse

Instance Method Details

#*(x) ⇒ Object

Operator for Proc#compose and Integer#times_collect/of.

a = lambda { |x| x + 4 }
b = lambda { |y| y / 2 }

(a * b).call(4)  #=> 6
(b * a).call(4)  #=> 4

CREDIT: Dave


29
30
31
32
33
34
35
36
37
38
39
# File 'lib/core/facets/proc/compose.rb', line 29

def *(x)
  if Integer===x
    # collect times
    c = []
    x.times{|i| c << call(i)}
    c
  else
    # compose procs
    lambda{|*a| self[x[*a]]}
  end
end

#bind(object = nil) ⇒ Object

Bind a Proc to an object returning a Method.

The block’s #to_s method (same as #inspect) is used for the temporary method label defined in the Object class.

NOTE: This dynamically loads thread.so if used.
NOTE: Not so sure it is thread critical anymore.


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
# File 'lib/core/facets/proc/bind.rb', line 12

def bind(object=nil)
  require 'thread'

  object = object || eval("self", self)
  block  = self
  store  = Object

  begin
    old, Thread.critical = Thread.critical, true
    @n ||= 0; @n += 1
    name = "_bind_#{@n}#{block.object_id}"
    store.module_eval do
      define_method name, &block
    end
    meth = object.method(name)
  ensure
    store.module_eval do
      remove_method name #rescue nil
      #undef_method name #rescue nil
    end
    Thread.critical = old
  end

  return meth
end

#compose(g) ⇒ Object

Returns a new proc that is the functional composition of two procs, in order.

a = lambda { |x| x + 4 }
b = lambda { |y| y / 2 }

a.compose(b).call(4)  #=> 6
b.compose(a).call(4)  #=> 4

CREDIT: Dave

Raises:

  • (ArgumentError)


14
15
16
17
# File 'lib/core/facets/proc/compose.rb', line 14

def compose(g)
  raise ArgumentError, "arity count mismatch" unless arity == g.arity
  lambda{ |*a| self[ *g[*a] ] }
end

#curry(*args) ⇒ Object

Curry Proc object into new Proc object.



44
45
46
47
48
49
50
51
# File 'lib/more/facets/curry.rb', line 44

def curry(*args)
  Proc.new do |*spice|
    result = args.collect do |a|
      MissingArgument == a ? spice.pop : a
    end
    call(*result)
  end
end

#to_hObject

Build a hash out of a Proc.

l = lambda { |s|
  s.a = 1
  s.b = 2
  s.c = 3
}
l.to_h  #=> {:a=>1, :b=>2, :c=>3}

CREDIT: Trans


249
250
251
252
253
254
# File 'lib/core/facets/conversion.rb', line 249

def to_h
  h = {}
  f = Functor.new{ |op, arg| h[op.to_s.chomp('=').to_sym] = arg }
  call( f )
  h
end

#to_method(name = nil, object = nil) ⇒ Object

Convert Proc to method.

Class X; end

plusproc = lambda { |x| x + 1 }
plusproc.to_method('foo', X)
X.new.foo(1)  #=> 2

TODO: Should use singleton instead of object.class ?

CREDIT: Trans


50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/core/facets/proc/bind.rb', line 50

def to_method(name=nil, object=nil)
  return bind unless name

  object = object || eval("self", self)
  klass  = object.class
  block  = self

  klass.class_eval do
    define_method name, &block
  end

  object.method(name)
end

#to_openobjectObject

Translates a Proc into an OpenObject. By droping an OpenObject into the Proc, the resulting assignments incured as the procedure is evaluated produce the OpenObject. This technique is simlar to that of MethodProbe.

p = lambda { |x|
  x.word = "Hello"
}
o = p.to_openobject
o.word #=> "Hello"

NOTE The Proc must have an arity of one –no more and no less.

Raises:

  • (ArgumentError)


234
235
236
237
238
239
# File 'lib/more/facets/openobject.rb', line 234

def to_openobject
  raise ArgumentError, 'bad arity for converting Proc to openobject' if arity != 1
  o = OpenObject.new
  self.call( o )
  o
end