Returns a hash of the named captures; each key is a capture name; each value is its captured string or nil
:
m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge") # => #<MatchData "hoge" foo:"h" bar:"ge"> m.named_captures # => {"foo"=>"h", "bar"=>"ge"} m = /(?<a>.)(?<b>.)/.match("01") # => #<MatchData "01" a:"0" b:"1"> m.named_captures #=> {"a" => "0", "b" => "1"} m = /(?<a>.)(?<b>.)?/.match("0") # => #<MatchData "0" a:"0" b:nil> m.named_captures #=> {"a" => "0", "b" => nil} m = /(?<a>.)(?<a>.)/.match("01") # => #<MatchData "01" a:"0" a:"1"> m.named_captures #=> {"a" => "1"}
If keyword argument symbolize_names
is given a true value, the keys in the resulting hash are Symbols:
m = /(?<a>.)(?<a>.)/.match("01") # => #<MatchData "01" a:"0" a:"1"> m.named_captures(symbolize_names: true) #=> {:a => "1"}
Returns the substring of the target string from its beginning up to the first match in self
(that is, self[0]
); equivalent to regexp global variable $`
:
m = /(.)(.)(\d+)(\d)/.match("THX1138.") # => #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8"> m[0] # => "HX1138" m.pre_match # => "T"
Related: MatchData#post_match
.
Returns the group most recently added to the stack.
Contrived example:
out = "" => "" q = PrettyPrint.new(out) => #<PrettyPrint:0x82f85c0 @output="", @maxwidth=79, @newline="\n", @genspace=#<Proc:0x82f8368@/home/vbatts/.rvm/rubies/ruby-head/lib/ruby/2.0.0/prettyprint.rb:82 (lambda)>, @output_width=0, @buffer_width=0, @buffer=[], @group_stack=[#<PrettyPrint::Group:0x82f8138 @depth=0, @breakables=[], @break=false>], @group_queue=#<PrettyPrint::GroupQueue:0x82fb7c0 @queue=[[#<PrettyPrint::Group:0x82f8138 @depth=0, @breakables=[], @break=false>]]>, @indent=0> q.group { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline q.group(q.current_group.depth + 1) { q.text q.current_group.inspect q.text q.newline } } } } => 284 puts out #<PrettyPrint::Group:0x8354758 @depth=1, @breakables=[], @break=false> #<PrettyPrint::Group:0x8354550 @depth=2, @breakables=[], @break=false> #<PrettyPrint::Group:0x83541cc @depth=3, @breakables=[], @break=false> #<PrettyPrint::Group:0x8347e54 @depth=4, @breakables=[], @break=false>
This is similar to breakable
except the decision to break or not is determined individually.
Two fill_breakable
under a group may cause 4 results: (break,break), (break,non-break), (non-break,break), (non-break,non-break). This is different to breakable
because two breakable
under a group may cause 2 results: (break,break), (non-break,non-break).
The text sep
is inserted if a line is not broken at this point.
If sep
is not specified, “ ” is used.
If width
is not specified, sep.length
is used. You will have to specify this when sep
is a multibyte character, for example.
Iterates over all IP addresses for name
.
Iterates over all IP addresses for name
.
Make obj
shareable between ractors.
obj
and all the objects it refers to will be frozen, unless they are already shareable.
If copy
keyword is true
, it will copy objects before freezing them, and will not modify obj
or its internal objects.
Note that the specification and implementation of this method are not mature and may be changed in the future.
obj = ['test'] Ractor.shareable?(obj) #=> false Ractor.make_shareable(obj) #=> ["test"] Ractor.shareable?(obj) #=> true obj.frozen? #=> true obj[0].frozen? #=> true # Copy vs non-copy versions: obj1 = ['test'] obj1s = Ractor.make_shareable(obj1) obj1.frozen? #=> true obj1s.object_id == obj1.object_id #=> true obj2 = ['test'] obj2s = Ractor.make_shareable(obj2, copy: true) obj2.frozen? #=> false obj2s.frozen? #=> true obj2s.object_id == obj2.object_id #=> false obj2s[0].object_id == obj2[0].object_id #=> false
See also the “Shareable and unshareable objects” section in the Ractor
class docs.
Returns the status of the global “ignore deadlock” condition. The default is false
, so that deadlock conditions are not ignored.
See also ::ignore_deadlock=
.
Returns the new state. When set to true
, the VM will not check for deadlock conditions. It is only useful to set this if your application can break a deadlock condition via some other means, such as a signal.
Thread.ignore_deadlock = true queue = Thread::Queue.new trap(:SIGUSR1){queue.push "Received signal"} # raises fatal error unless ignoring deadlock puts queue.pop
See also ::ignore_deadlock
.
Returns an array of the names of the thread-local variables (as Symbols).
thr = Thread.new do Thread.current.thread_variable_set(:cat, 'meow') Thread.current.thread_variable_set("dog", 'woof') end thr.join #=> #<Thread:0x401b3f10 dead> thr.thread_variables #=> [:dog, :cat]
Note that these are not fiber local variables. Please see Thread#[]
and Thread#thread_variable_get
for more details.
Returns true
if the given string (or symbol) exists as a thread-local variable.
me = Thread.current me.thread_variable_set(:oliver, "a") me.thread_variable?(:oliver) #=> true me.thread_variable?(:stanley) #=> false
Note that these are not fiber local variables. Please see Thread#[]
and Thread#thread_variable_get
for more details.
In general, while a TracePoint
callback is running, other registered callbacks are not called to avoid confusion by reentrance. This method allows the reentrance in a given block. This method should be used carefully, otherwise the callback can be easily called infinitely.
If this method is called when the reentrance is already allowed, it raises a RuntimeError
.
Example:
# Without reentry # --------------- line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # only work in this file puts "Line handler" binding.eval("class C; end") end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This script will print "Class handler" only once: when inside :line # handler, all other handlers are ignored # With reentry # ------------ line_handler = TracePoint.new(:line) do |tp| next if tp.path != __FILE__ # only work in this file next if (__LINE__..__LINE__+3).cover?(tp.lineno) # don't be invoked from itself puts "Line handler" TracePoint.allow_reentry { binding.eval("class C; end") } end.enable class_handler = TracePoint.new(:class) do |tp| puts "Class handler" end.enable class B end # This wil print "Class handler" twice: inside allow_reentry block in :line # handler, other handlers are enabled.
Note that the example shows the principal effect of the method, but its practical usage is for debugging libraries that sometimes require other libraries hooks to not be affected by debugger being inside trace point handling. Precautions should be taken against infinite recursion in this case (note that we needed to filter out calls by itself from :line handler, otherwise it will call itself infinitely).
Return value from :return
, :c_return
, and :b_return
event
Returns true
if yield
would execute a block in the current context. The iterator?
form is mildly deprecated.
def try if block_given? yield else "no block" end end try #=> "no block" try { "hello" } #=> "hello" try do "hello" end #=> "hello"
With argument pattern
, returns an enumerator that uses the pattern to partition elements into arrays (“slices”). An element begins a new slice if element === pattern
(or if it is the first element).
a = %w[foo bar fop for baz fob fog bam foy] e = a.slice_before(/ba/) # => #<Enumerator: ...> e.each {|array| p array }
Output:
["foo"] ["bar", "fop", "for"] ["baz", "fob", "fog"] ["bam", "foy"]
With a block, returns an enumerator that uses the block to partition elements into arrays. An element begins a new slice if its block return is a truthy value (or if it is the first element):
e = (1..20).slice_before {|i| i % 4 == 2 } # => #<Enumerator: ...> e.each {|array| p array }
Output:
[1] [2, 3, 4, 5] [6, 7, 8, 9] [10, 11, 12, 13] [14, 15, 16, 17] [18, 19, 20]
Other methods of the Enumerator
class and Enumerable
module, such as to_a
, map
, etc., are also usable.
For example, iteration over ChangeLog entries can be implemented as follows:
# iterate over ChangeLog entries. open("ChangeLog") { |f| f.slice_before(/\A\S/).each { |e| pp e } } # same as above. block is used instead of pattern argument. open("ChangeLog") { |f| f.slice_before { |line| /\A\S/ === line }.each { |e| pp e } }
“svn proplist -R” produces multiline output for each file. They can be chunked as follows:
IO.popen([{"LC_ALL"=>"C"}, "svn", "proplist", "-R"]) { |f| f.lines.slice_before(/\AProp/).each { |lines| p lines } } #=> ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"] # ["Properties on 'goruby.c':\n", " svn:eol-style\n"] # ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"] # ["Properties on 'regparse.c':\n", " svn:eol-style\n"] # ...
If the block needs to maintain state over multiple elements, local variables can be used. For example, three or more consecutive increasing numbers can be squashed as follows (see chunk_while
for a better way):
a = [0, 2, 3, 4, 6, 7, 9] prev = a[0] p a.slice_before { |e| prev, prev2 = e, prev prev2 + 1 != e }.map { |es| es.length <= 2 ? es.join(",") : "#{es.first}-#{es.last}" }.join(",") #=> "0,2-4,6,7,9"
However local variables should be used carefully if the result enumerator is enumerated twice or more. The local variables should be initialized for each enumeration. Enumerator.new
can be used to do it.
# Word wrapping. This assumes all characters have same width. def wordwrap(words, maxwidth) Enumerator.new {|y| # cols is initialized in Enumerator.new. cols = 0 words.slice_before { |w| cols += 1 if cols != 0 cols += w.length if maxwidth < cols cols = w.length true else false end }.each {|ws| y.yield ws } } end text = (1..20).to_a.join(" ") enum = wordwrap(text.split(/\s+/), 10) puts "-"*10 enum.each { |ws| puts ws.join(" ") } # first enumeration. puts "-"*10 enum.each { |ws| puts ws.join(" ") } # second enumeration generates same result as the first. puts "-"*10 #=> ---------- # 1 2 3 4 5 # 6 7 8 9 10 # 11 12 13 # 14 15 16 # 17 18 19 # 20 # ---------- # 1 2 3 4 5 # 6 7 8 9 10 # 11 12 13 # 14 15 16 # 17 18 19 # 20 # ----------
mbox contains series of mails which start with Unix From line. So each mail can be extracted by slice before Unix From line.
# parse mbox open("mbox") { |f| f.slice_before { |line| line.start_with? "From " }.each { |mail| unix_from = mail.shift i = mail.index("\n") header = mail[0...i] body = mail[(i+1)..-1] body.pop if body.last == "\n" fields = header.slice_before { |line| !" \t".include?(line[0]) }.to_a p unix_from pp fields pp body } } # split mails in mbox (slice before Unix From line after an empty line) open("mbox") { |f| emp = true f.slice_before { |line| prevemp = emp emp = line == "\n" prevemp && line.start_with?("From ") }.each { |mail| mail.pop if mail.last == "\n" pp mail } }
Returns a hash that contains filename as key and coverage array as value. This is the same as ‘Coverage.result(stop: false, clear: false)`.
{ "file.rb" => [1, 2, nil], ... }
Sets create identifier, which is used to decide if the json_create hook of a class should be called; initial value is json_class
:
JSON.create_id # => 'json_class'
Returns the current create identifier. See also JSON.create_id=
.
Arguments obj
and opts
here are the same as arguments obj
and opts
in JSON.generate
.
Default options are:
{ indent: ' ', # Two spaces space: ' ', # One space array_nl: "\n", # Newline object_nl: "\n" # Newline }
Example:
obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} json = JSON.pretty_generate(obj) puts json
Output:
{ "foo": [ "bar", "baz" ], "bat": { "bam": 0, "bad": 1 } }
Return consuming memory size of obj in bytes.
Note that the return size is incomplete. You need to deal with this information as only a HINT. Especially, the size of T_DATA
may not be correct.
This method is only expected to work with C Ruby.
From Ruby 2.2, memsize_of
(obj) returns a memory size includes sizeof(RVALUE).
Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an effect for FIPS-capable installations of the OpenSSL
library. Trying to do so otherwise will result in an error.
OpenSSL.fips_mode = true # turn FIPS mode on OpenSSL.fips_mode = false # and off again
If file_name is readable by others, returns an integer representing the file permission bits of file_name. Returns nil
otherwise. The meaning of the bits is platform dependent; on Unix systems, see stat(2)
.
file_name can be an IO
object.
File.world_readable?("/etc/passwd") #=> 420 m = File.world_readable?("/etc/passwd") sprintf("%o", m) #=> "644"