Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions core/hash.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,39 @@ class Hash[unchecked out K, unchecked out V]
| [K, V] (array[ _Pair[K, V] ] two_element_arrays) -> instance
| [T] (*T objects) -> Hash[T, T]

# <!--
# rdoc-file=hash.c
# - Hash.ruby2_keywords_hash(hash) -> hash
# -->
# Duplicates a given hash and adds a ruby2_keywords flag. This method is not for
# casual use; debugging, researching, and some truly necessary cases like
# deserialization of arguments.
#
# h = {k: 1}
# h = Hash.ruby2_keywords_hash(h)
# def foo(k: 42)
# k
# end
# foo(*[h]) #=> 1 with neither a warning or an error
#
def self.ruby2_keywords_hash: [H < Hash[untyped, untyped]] (H hash) -> H

# <!--
# rdoc-file=hash.c
# - Hash.ruby2_keywords_hash?(hash) -> true or false
# -->
# Checks if a given hash is flagged by Module#ruby2_keywords (or
# Proc#ruby2_keywords). This method is not for casual use; debugging,
# researching, and some truly necessary cases like serialization of arguments.
#
# ruby2_keywords def foo(*args)
# Hash.ruby2_keywords_hash?(args.last)
# end
# foo(k: 1) #=> true
# foo({k: 1}) #=> false
#
def self.ruby2_keywords_hash?: (Hash[untyped, untyped] hash) -> bool

# <!--
# rdoc-file=hash.c
# - Hash.try_convert(object) -> object, new_hash, or nil
Expand Down
119 changes: 119 additions & 0 deletions core/kernel.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,86 @@ module Kernel : BasicObject
def call: (untyped argument) -> void
end

# <!--
# rdoc-file=vm_trace.c
# - set_trace_func(proc) -> proc
# - set_trace_func(nil) -> nil
# -->
# Establishes *proc* as the handler for tracing, or disables tracing if the
# parameter is `nil`.
#
# <strong>Note:</strong> this method is obsolete, please use TracePoint instead.
#
# *proc* takes up to six parameters:
#
# * an event name string
# * a filename string
# * a line number
# * a method name symbol, or nil
# * a binding, or nil
# * the class, module, or nil
#
# *proc* is invoked whenever an event occurs.
#
# Events are:
#
# <code>"c-call"</code>
# : call a C-language routine
#
# <code>"c-return"</code>
# : return from a C-language routine
#
# <code>"call"</code>
# : call a Ruby method
#
# <code>"class"</code>
# : start a class or module definition
#
# <code>"end"</code>
# : finish a class or module definition
#
# <code>"line"</code>
# : execute code on a new line
#
# <code>"raise"</code>
# : raise an exception
#
# <code>"return"</code>
# : return from a Ruby method
#
#
# Tracing is disabled within the context of *proc*.
#
# class Test
# def test
# a = 1
# b = 2
# end
# end
#
# set_trace_func proc { |event, file, line, id, binding, class_or_module|
# printf "%8s %s:%-2d %16p %14p\n", event, file, line, id, class_or_module
# }
# t = Test.new
# t.test
#
# Produces:
#
# c-return prog.rb:8 :set_trace_func Kernel
# line prog.rb:11 nil nil
# c-call prog.rb:11 :new Class
# c-call prog.rb:11 :initialize BasicObject
# c-return prog.rb:11 :initialize BasicObject
# c-return prog.rb:11 :new Class
# line prog.rb:12 nil nil
# call prog.rb:2 :test Test
# line prog.rb:3 :test Test
# line prog.rb:4 :test Test
# return prog.rb:5 :test Test
#
def self?.set_trace_func: (Proc proc) -> Proc
| (nil) -> nil

# <!--
# rdoc-file=eval.c
# - trace_var(symbol, cmd ) -> nil
Expand Down Expand Up @@ -2279,6 +2359,45 @@ module Kernel : BasicObject
| [T < _Tracer] (interned name, T cmd) -> [T]?
| (interned name, untyped cmd) -> nil

# <!--
# rdoc-file=signal.c
# - Signal.trap(signal, command) -> obj
# - Signal.trap(signal) { ... } -> obj
# -->
# Specifies the handling of signals. Returns the previous handler for the given
# signal.
#
# Argument `signal` is a signal name (a string or symbol such as `SIGALRM` or
# `SIGUSR1`) or an integer signal number. When `signal` is a string or symbol,
# the leading characters `SIG` may be omitted.
#
# Argument `command` or block provided specifies code to be run when the signal
# is raised.
#
# Argument `command` may also be a string or symbol with the following special
# values:
#
# * `IGNORE`, `SIG_IGN`: the signal will be ignored.
# * `DEFAULT`, `SIG_DFL`: Ruby's default handler will be invoked.
# * `EXIT`: the process will be terminated by the signal.
# * `SYSTEM_DEFAULT`: the operating system's default handler will be invoked.
#
# The special signal name `EXIT` or signal number zero will be invoked just
# prior to program termination:
#
# Signal.trap(0, proc { puts "Terminating: #{$$}" })
# Signal.trap("CLD") { puts "Child died" }
# fork && Process.wait
#
# Outputs:
#
# Terminating: 27461
# Child died
# Terminating: 27460
#
def self?.trap: (Integer | interned signal) { (Integer) -> void } -> Signal::trap_command
| (Integer | interned signal, Signal::trap_command command) -> Signal::trap_command

# <!--
# rdoc-file=object.c
# - obj !~ other -> true or false
Expand Down
76 changes: 76 additions & 0 deletions core/process.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,29 @@ module Process
#
def self.kill: (Integer | interned signal, *Integer pids) -> Integer

# <!--
# rdoc-file=process.c
# - Process.last_status -> Process::Status or nil
# -->
# Returns a Process::Status object representing the most recently exited child
# process in the current thread, or `nil` if none:
#
# Process.spawn('ruby', '-e', 'exit 13')
# Process.wait
# Process.last_status # => #<Process::Status: pid 14396 exit 13>
#
# Process.spawn('ruby', '-e', 'exit 14')
# Process.wait
# Process.last_status # => #<Process::Status: pid 4692 exit 14>
#
# Process.spawn('ruby', '-e', 'exit 15')
# # 'exit 15' has not been reaped by #wait.
# Process.last_status # => #<Process::Status: pid 4692 exit 14>
# Process.wait
# Process.last_status # => #<Process::Status: pid 1380 exit 15>
#
def self.last_status: () -> Process::Status?

# <!--
# rdoc-file=process.c
# - Process.maxgroups -> integer
Expand Down Expand Up @@ -1029,6 +1052,16 @@ module Process
#
def self.setpgid: (Integer pid, Integer arg0) -> Integer

# <!--
# rdoc-file=process.c
# - Process.setpgrp -> 0
# -->
# Equivalent to <code>setpgid(0, 0)</code>.
#
# Not available on all platforms.
#
def self.setpgrp: () -> Integer

# <!--
# rdoc-file=process.c
# - Process.setpriority(kind, integer, priority) -> 0
Expand Down Expand Up @@ -1857,6 +1890,35 @@ end
# stat.exitstatus # => 99
#
class Process::Status < Object
# <!--
# rdoc-file=process.c
# - Process::Status.wait(pid = -1, flags = 0) -> Process::Status
# -->
# Like Process.wait, but returns a Process::Status object (instead of an integer
# pid or nil); see Process.wait for the values of `pid` and `flags`.
#
# If there are child processes, waits for a child process to exit and returns a
# Process::Status object containing information on that process; sets
# thread-local variable <code>$?</code>:
#
# Process.spawn('cat /nop') # => 1155880
# Process::Status.wait # => #<Process::Status: pid 1155880 exit 1>
# $? # => #<Process::Status: pid 1155508 exit 1>
#
# If there is no child process, returns an "empty" Process::Status object that
# does not represent an actual process; does not set thread-local variable
# <code>$?</code>:
#
# Process::Status.wait # => #<Process::Status: pid -1 exit 0>
# $? # => #<Process::Status: pid 1155508 exit 1> # Unchanged.
#
# May invoke the scheduler hook Fiber::Scheduler#process_wait.
#
# Not available on all platforms.
#
def self.wait: (?int pid) -> Process::Status
| (int pid, int flags) -> Process::Status?

# <!--
# rdoc-file=process.c
# - stat & mask -> integer
Expand Down Expand Up @@ -2041,6 +2103,20 @@ end
# Process::GID modules.
#
module Process::Sys
# <!--
# rdoc-file=process.c
# - Process.egid -> integer
# - Process::GID.eid -> integer
# - Process::Sys.geteid -> integer
# -->
# Returns the effective group ID for the current process:
#
# Process.egid # => 500
#
# Not available on all platforms.
#
def self.getegid: () -> Integer

# <!--
# rdoc-file=process.c
# - Process.euid -> integer
Expand Down
14 changes: 14 additions & 0 deletions test/stdlib/Hash_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ def test_new
Hash, :new, capacity: capacity do 1r end
end
end

def test_ruby2_keywords_hash
assert_send_type "(Hash[Symbol, Integer]) -> Hash[Symbol, Integer]",
Hash, :ruby2_keywords_hash, { k: 1 }
assert_send_type "(HashSingletonTest::Subclass) -> HashSingletonTest::Subclass",
Hash, :ruby2_keywords_hash, Subclass[k: 1]
end

def test_ruby2_keywords_hash?
assert_send_type "(Hash[Symbol, Integer]) -> bool",
Hash, :ruby2_keywords_hash?, { k: 1 }
assert_send_type "(Hash[Symbol, Integer]) -> bool",
Hash, :ruby2_keywords_hash?, Hash.ruby2_keywords_hash({ k: 1 })
end
end

class HashInstanceTest < Test::Unit::TestCase
Expand Down
25 changes: 25 additions & 0 deletions test/stdlib/Kernel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,31 @@ def test_rand
assert_send_type "(Range[Float]) -> nil", Kernel, :rand, 0.0...0.0
end

def test_set_trace_func
assert_send_type "(Proc) -> Proc",
Kernel, :set_trace_func, proc {}
assert_send_type "(nil) -> nil",
Kernel, :set_trace_func, nil
ensure
set_trace_func(nil)
end

def test_trap
old_usr2 = trap(:USR2, nil)

with_interned(:USR2).and(Signal.list["USR2"]) do |signal|
assert_send_type "(Integer | ::interned) { (Integer) -> void } -> Signal::trap_command",
Kernel, :trap, signal do |n| end

with_string("").and(with_bool, nil, Class.new { def call(x) end }.new) do |command|
assert_send_type "(Integer | ::interned, Signal::trap_command) -> Signal::trap_command",
Kernel, :trap, signal, command
end
end
ensure
trap(:USR2, old_usr2)
end

def test_trace_var
tracer = BlankSlate.new
def tracer.call(new) nil end
Expand Down
Loading
Loading