Files
mruby-mruby/mrbgems/mruby-proc-ext
Yukihiro "Matz" Matsumoto 20b9002214 class.c: merge conditional methods into ROM tables
Move conditional mrb_define_method_id() calls into ROM entry
arrays using #ifdef guards. With linear search, sizeof in
MRB_MT_ROM_TAB() adjusts automatically after preprocessing.

Cross-class ROM tables (methods a gem defines on a class it does
not own) are reverted to mrb_define_method_id(). Multiple gems
should not add ROM table layers to the same class; each layer
costs a 16-byte mrb_mt_tbl struct in RAM and deepens the lookup
chain. Use mrb_define_method_id() for cross-class methods.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 11:05:03 +09:00
..
2025-06-10 11:07:16 +09:00

mruby-proc-ext

This mrbgem extends the functionality of the Proc class in mruby, providing additional methods for common operations and introspection.

Features

This gem adds the following methods to the Proc class:

  • ===: Alias for Proc#call. Allows procs to be used in case statements.

    upcase_proc = ->(s) { s.upcase }
    case "hello"
    when upcase_proc
      # this won't match directly, but demonstrates usage if proc returned boolean
    end
    # More practically:
    is_even = ->(n) { n % 2 == 0 }
    puts "4 is even" if is_even === 4 # => true
    
  • yield: Alias for Proc#call.

    add_one = ->(x) { x + 1 }
    puts add_one.yield(5) # => 6
    
  • to_proc: Returns self. Useful for methods expecting a proc.

    p = Proc.new { |x| x * 2 }
    [1, 2, 3].map(&p.to_proc) # => [2, 4, 6]
    
  • curry(arity=self.arity): Returns a curried proc.

    adder = ->(a, b, c) { a + b + c }
    curried_adder = adder.curry
    add5 = curried_adder.call(2, 3)
    puts add5.call(4) # => 9
    
    mul = ->(x,y) { x * y }
    mul_by_5 = mul.curry.call(5)
    puts mul_by_5.call(3) # => 15
    
  • << (composition): Returns a new proc that represents the composition of two procs (g << f is g(f(x))).

    add_one = ->(x) { x + 1 }
    double_it = ->(x) { x * 2 }
    composed_proc = double_it << add_one # double_it(add_one(x))
    puts composed_proc.call(5) # => double_it(6) => 12
    
  • >> (composition): Returns a new proc that represents the composition of two procs (f >> g is g(f(x))).

    add_one = ->(x) { x + 1 }
    double_it = ->(x) { x * 2 }
    composed_proc = add_one >> double_it # double_it(add_one(x))
    puts composed_proc.call(5) # => double_it(6) => 12
    
  • lambda?: Returns true if the proc is a lambda, false otherwise.

    my_lambda = -> {}
    my_proc = Proc.new {}
    puts my_lambda.lambda? # => true
    puts my_proc.lambda?  # => false
    
  • source_location: Returns an array containing the source filename and line number where the proc was defined, or nil if this information is not available.

    # Assuming this code is in "test.rb" at line 5
    my_proc = Proc.new {}
    p my_proc.source_location # => ["test.rb", 5] (if debug info enabled)
    
  • inspect: Returns a string containing a human-readable representation of the proc, including its source location (if available) and whether it's a lambda.

    my_lambda = ->(x) { x * 2 }
    # Might output: #<Proc:0x... test.rb:1 (lambda)>
    puts my_lambda.inspect
    
  • parameters: Returns an array of arrays, describing the parameters accepted by the proc. Each inner array contains the parameter type (:req, :opt, :rest, :key, :keyrest, :block) and its name.

    prc = ->(a, b=20, *rest, keyparam:, &blk) { }
    p prc.parameters
    # => [[:req, :a], [:opt, :b], [:rest, :rest], [:keyreq, :keyparam], [:block, :blk]]
    

This gem also adds:

  • Kernel#proc: Creates a new proc from a block. This is similar to Proc.new but ensures the created proc is not a lambda.

    p1 = proc { |a| a }
    puts p1.lambda? # => false