Skip to content

Commit

Permalink
Update Proc
Browse files Browse the repository at this point in the history
  • Loading branch information
sampersand authored and soutaro committed Jul 25, 2024
1 parent 22e9be4 commit 712667d
Show file tree
Hide file tree
Showing 2 changed files with 305 additions and 72 deletions.
207 changes: 184 additions & 23 deletions core/proc.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,184 @@
#
# Numbered parameters were introduced in Ruby 2.7.
#
class Proc < Object
def clone: () -> self
class Proc
interface _Callable
def call: (*untyped, **untyped) ?{ (*untyped, **untyped) -> untyped } -> untyped
end

# <!--
# rdoc-file=proc.c
# - Proc.new {|...| block } -> a_proc
# -->
# Creates a new Proc object, bound to the current context.
#
# proc = Proc.new { "hello" }
# proc.call #=> "hello"
#
# Raises ArgumentError if called without a block.
#
# Proc.new #=> ArgumentError
#
def self.new: () { (*untyped, **untyped) -> untyped } -> instance

def clone: () -> instance
def dup: () -> instance

# <!-- rdoc-file=proc.c -->
# Invokes the block, setting the block's parameters to the values in *params*
# using something close to method calling semantics. Returns the value of the
# last expression evaluated in the block.
#
# a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
# a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
# a_proc[9, 1, 2, 3] #=> [9, 18, 27]
# a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
# a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
#
# Note that `prc.()` invokes `prc.call()` with the parameters given. It's
# syntactic sugar to hide "call".
#
# For procs created using #lambda or `->()` an error is generated if the wrong
# number of parameters are passed to the proc. For procs created using Proc.new
# or Kernel.proc, extra parameters are silently discarded and missing parameters
# are set to `nil`.
#
# a_proc = proc {|a,b| [a,b] }
# a_proc.call(1) #=> [1, nil]
#
# a_proc = lambda {|a,b| [a,b] }
# a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
#
# See also Proc#lambda?.
#
alias === call

# <!-- rdoc-file=proc.c -->
# Invokes the block, setting the block's parameters to the values in *params*
# using something close to method calling semantics. Returns the value of the
# last expression evaluated in the block.
#
# a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
# a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
# a_proc[9, 1, 2, 3] #=> [9, 18, 27]
# a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
# a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
#
# Note that `prc.()` invokes `prc.call()` with the parameters given. It's
# syntactic sugar to hide "call".
#
# For procs created using #lambda or `->()` an error is generated if the wrong
# number of parameters are passed to the proc. For procs created using Proc.new
# or Kernel.proc, extra parameters are silently discarded and missing parameters
# are set to `nil`.
#
# a_proc = proc {|a,b| [a,b] }
# a_proc.call(1) #=> [1, nil]
#
# a_proc = lambda {|a,b| [a,b] }
# a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
#
# See also Proc#lambda?.
#
alias yield call

# <!--
# rdoc-file=proc.c
# - prc << g -> a_proc
# -->
# Returns a proc that is the composition of this proc and the given *g*. The
# returned proc takes a variable number of arguments, calls *g* with them then
# calls this proc with the result.
#
# f = proc {|x| x * x }
# g = proc {|x| x + x }
# p (f << g).call(2) #=> 16
#
# See Proc#>> for detailed explanations.
#
def <<: (_Callable callable) -> Proc

# <!--
# rdoc-file=proc.c
# - prc >> g -> a_proc
# -->
# Returns a proc that is the composition of this proc and the given *g*. The
# returned proc takes a variable number of arguments, calls this proc with them
# then calls *g* with the result.
#
# f = proc {|x| x * x }
# g = proc {|x| x + x }
# p (f >> g).call(2) #=> 8
#
# *g* could be other Proc, or Method, or any other object responding to `call`
# method:
#
# class Parser
# def self.call(text)
# # ...some complicated parsing logic...
# end
# end
#
# pipeline = File.method(:read) >> Parser >> proc { |data| puts "data size: #{data.count}" }
# pipeline.call('data.json')
#
# See also Method#>> and Method#<<.
#
def >>: (_Callable callable) -> Proc

# <!--
# rdoc-file=proc.c
# - prc == other -> true or false
# - prc.eql?(other) -> true or false
# -->
# Two procs are the same if, and only if, they were created from the same code
# block.
#
# def return_block(&block)
# block
# end
#
# def pass_block_twice(&block)
# [return_block(&block), return_block(&block)]
# end
#
# block1, block2 = pass_block_twice { puts 'test' }
# # Blocks might be instantiated into Proc's lazily, so they may, or may not,
# # be the same object.
# # But they are produced from the same code block, so they are equal
# block1 == block2
# #=> true
#
# # Another Proc will never be equal, even if the code is the "same"
# block1 == proc { puts 'test' }
# #=> false
#
def ==: (untyped other) -> bool

# <!-- rdoc-file=proc.c -->
# Two procs are the same if, and only if, they were created from the same code
# block.
#
# def return_block(&block)
# block
# end
#
# def pass_block_twice(&block)
# [return_block(&block), return_block(&block)]
# end
#
# block1, block2 = pass_block_twice { puts 'test' }
# # Blocks might be instantiated into Proc's lazily, so they may, or may not,
# # be the same object.
# # But they are produced from the same code block, so they are equal
# block1 == block2
# #=> true
#
# # Another Proc will never be equal, even if the code is the "same"
# block1 == proc { puts 'test' }
# #=> false
#
alias eql? ==

# <!--
# rdoc-file=proc.c
Expand Down Expand Up @@ -379,7 +555,7 @@ class Proc < Object
#
# See also Proc#lambda?.
#
def call: (*untyped arg0) -> untyped
def call: (*untyped, **untyped) ?{ (*untyped, **untyped) -> untyped } -> untyped

# <!-- rdoc-file=proc.c -->
# Invokes the block, setting the block's parameters to the values in *params*
Expand Down Expand Up @@ -408,7 +584,7 @@ class Proc < Object
#
# See also Proc#lambda?.
#
def []: (*untyped arg0) -> untyped
alias [] call

# <!--
# rdoc-file=proc.c
Expand Down Expand Up @@ -455,7 +631,7 @@ class Proc < Object
# b = proc { :foo }
# p b.curry[] #=> :foo
#
def curry: (?_ToInt arity) -> Proc
def curry: (?int? arity) -> Proc

# <!--
# rdoc-file=proc.c
Expand All @@ -467,21 +643,6 @@ class Proc < Object
#
def hash: () -> Integer

# <!--
# rdoc-file=proc.c
# - Proc.new {|...| block } -> a_proc
# -->
# Creates a new Proc object, bound to the current context.
#
# proc = Proc.new { "hello" }
# proc.call #=> "hello"
#
# Raises ArgumentError if called without a block.
#
# Proc.new #=> ArgumentError
#
def initialize: () { (?) -> untyped } -> void

# <!--
# rdoc-file=proc.c
# - prc.lambda? -> true or false
Expand Down Expand Up @@ -602,7 +763,7 @@ class Proc < Object
# prc = lambda{|x, y=42, *other|}
# prc.parameters(lambda: false) #=> [[:opt, :x], [:opt, :y], [:rest, :other]]
#
def parameters: (?lambda: boolish) -> ::Array[[ Symbol, Symbol ]]
def parameters: (?lambda: boolish) -> Method::param_types

# <!--
# rdoc-file=proc.c
Expand All @@ -611,7 +772,7 @@ class Proc < Object
# Returns the Ruby source filename and line number containing this proc or `nil`
# if this proc was not defined in Ruby (i.e. native).
#
def source_location: () -> [ String, Integer ]
def source_location: () -> [String, Integer]?

# <!--
# rdoc-file=proc.c
Expand All @@ -635,5 +796,5 @@ class Proc < Object
# Returns the unique identifier for this proc, along with an indication of where
# the proc was defined.
#
def inspect: () -> String
alias inspect to_s
end
Loading

0 comments on commit 712667d

Please sign in to comment.