Results for: "Logger"

Returns the Ruby source filename and line number of the binding 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).

Returns the Ruby source filename and line number containing this method or nil if this method was not defined in Ruby (i.e. native).

Returns a Method of superclass which would be called when super is used or nil if there is no method on superclass.

Returns the Ruby source filename and line number containing this method or nil if this method was not defined in Ruby (i.e. native).

Returns a Method of superclass which would be called when super is used or nil if there is no method on superclass.

Closes the incoming port and returns whether it was already closed. All further attempts to Ractor.receive in the ractor, and send to the ractor will fail with Ractor::ClosedError.

r = Ractor.new {sleep(500)}
r.close_incoming  #=> false
r.close_incoming  #=> true
r.send('test')
# Ractor::ClosedError (The incoming-port is already closed)

Closes the outgoing port and returns whether it was already closed. All further attempts to Ractor.yield in the ractor, and take from the ractor will fail with Ractor::ClosedError.

r = Ractor.new {sleep(500)}
r.close_outgoing  #=> false
r.close_outgoing  #=> true
r.take
# Ractor::ClosedError (The outgoing-port is already closed)

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.

Changes asynchronous interrupt timing.

interrupt means asynchronous event and corresponding procedure by Thread#raise, Thread#kill, signal trap (not supported yet) and main thread termination (if main thread terminates, then all other thread will be killed).

The given hash has pairs like ExceptionClass => :TimingSymbol. Where the ExceptionClass is the interrupt handled by the given block. The TimingSymbol can be one of the following symbols:

:immediate

Invoke interrupts immediately.

:on_blocking

Invoke interrupts while BlockingOperation.

:never

Never invoke all interrupts.

BlockingOperation means that the operation will block the calling thread, such as read and write. On CRuby implementation, BlockingOperation is any operation executed without GVL.

Masked asynchronous interrupts are delayed until they are enabled. This method is similar to sigprocmask(3).

NOTE

Asynchronous interrupts are difficult to use.

If you need to communicate between threads, please consider to use another way such as Queue.

Or use them with deep understanding about this method.

Usage

In this example, we can guard from Thread#raise exceptions.

Using the :never TimingSymbol the RuntimeError exception will always be ignored in the first block of the main thread. In the second ::handle_interrupt block we can purposefully handle RuntimeError exceptions.

th = Thread.new do
  Thread.handle_interrupt(RuntimeError => :never) {
    begin
      # You can write resource allocation code safely.
      Thread.handle_interrupt(RuntimeError => :immediate) {
        # ...
      }
    ensure
      # You can write resource deallocation code safely.
    end
  }
end
Thread.pass
# ...
th.raise "stop"

While we are ignoring the RuntimeError exception, it’s safe to write our resource allocation code. Then, the ensure block is where we can safely deallocate your resources.

Stack control settings

It’s possible to stack multiple levels of ::handle_interrupt blocks in order to control more than one ExceptionClass and TimingSymbol at a time.

Thread.handle_interrupt(FooError => :never) {
  Thread.handle_interrupt(BarError => :never) {
     # FooError and BarError are prohibited.
  }
}

Inheritance with ExceptionClass

All exceptions inherited from the ExceptionClass parameter will be considered.

Thread.handle_interrupt(Exception => :never) {
  # all exceptions inherited from Exception are prohibited.
}

For handling all interrupts, use Object and not Exception as the ExceptionClass, as kill/terminate interrupts are not handled by Exception.

Returns whether or not the asynchronous queue is empty.

Since Thread::handle_interrupt can be used to defer asynchronous events, this method can be used to determine if there are any deferred events.

If you find this method returns true, then you may finish :never blocks.

For example, the following method processes deferred asynchronous events immediately.

def Thread.kick_interrupt_immediately
  Thread.handle_interrupt(Object => :immediate) {
    Thread.pass
  }
end

If error is given, then check only for error type deferred events.

Usage

th = Thread.new{
  Thread.handle_interrupt(RuntimeError => :on_blocking){
    while true
      ...
      # reach safe point to invoke interrupt
      if Thread.pending_interrupt?
        Thread.handle_interrupt(Object => :immediate){}
      end
      ...
    end
  }
}
...
th.raise # stop thread

This example can also be written as the following, which you should use to avoid asynchronous interrupts.

flag = true
th = Thread.new{
  Thread.handle_interrupt(RuntimeError => :on_blocking){
    while true
      ...
      # reach safe point to invoke interrupt
      break if flag == false
      ...
    end
  }
}
...
flag = false # stop thread

Returns whether or not the asynchronous queue is empty for the target thread.

If error is given, then check only for error type deferred events.

See ::pending_interrupt? for more information.

Returns the execution stack for the target thread—an array containing backtrace location objects.

See Thread::Backtrace::Location for more information.

This method behaves similarly to Kernel#caller_locations except it applies to a specific thread.

Generally, while a TracePoint callback is running, other registered callbacks are not called to avoid confusion from reentrance. This method allows reentrance within a given block. Use this method carefully to avoid infinite callback invocation.

If called when reentrance is already allowed, it raises a RuntimeError.

Example:

# Without reentry
# ---------------

line_handler = TracePoint.new(:line) do |tp|
  next if tp.path != __FILE__ # Only works 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 the :line
# handler, all other handlers are ignored.

# With reentry
# ------------

line_handler = TracePoint.new(:line) do |tp|
  next if tp.path != __FILE__ # Only works in this file
  next if (__LINE__..__LINE__+3).cover?(tp.lineno) # Prevent infinite calls
  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 will print "Class handler" twice: inside the allow_reentry block in the :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 the 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 the :line handler, otherwise it would call itself infinitely).

Returns an array of the names of global variables. This includes special regexp global variables such as $~ and $+, but does not include the numbered regexp global variables ($1, $2, etc.).

global_variables.grep /std/   #=> [:$stdin, :$stdout, :$stderr]

Returns the names of the current local variables.

fred = 1
for i in 1..10
   # ...
end
local_variables   #=> [:fred, :i]

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"

Returns an array containing truthy elements returned by the block.

With a block given, calls the block with successive elements; returns an array containing each truthy value returned by the block:

(0..9).filter_map {|i| i * 2 if i.even? }                              # => [0, 4, 8, 12, 16]
{foo: 0, bar: 1, baz: 2}.filter_map {|key, value| key if value.even? } # => [:foo, :baz]

When no block given, returns an Enumerator.

With a block given, calls the block with each element, but in reverse order; returns self:

a = []
(1..4).reverse_each {|element| a.push(-element) } # => 1..4
a # => [-4, -3, -2, -1]

a = []
%w[a b c d].reverse_each {|element| a.push(element) }
# => ["a", "b", "c", "d"]
a # => ["d", "c", "b", "a"]

a = []
h.reverse_each {|element| a.push(element) }
# => {:foo=>0, :bar=>1, :baz=>2}
a # => [[:baz, 2], [:bar, 1], [:foo, 0]]

With no block given, returns an Enumerator.

Creates an enumerator for each chunked elements. The ends of chunks are defined by pattern and the block.

If pattern === elt returns true or the block returns true for the element, the element is end of a chunk.

The === and block is called from the first element to the last element of enum.

The result enumerator yields the chunked elements as an array. So each method can be called as follows:

enum.slice_after(pattern).each { |ary| ... }
enum.slice_after { |elt| bool }.each { |ary| ... }

Other methods of the Enumerator class and Enumerable module, such as map, etc., are also usable.

For example, continuation lines (lines end with backslash) can be concatenated as follows:

lines = ["foo\n", "bar\\\n", "baz\n", "\n", "qux\n"]
e = lines.slice_after(/(?<!\\)\n\z/)
p e.to_a
#=> [["foo\n"], ["bar\\\n", "baz\n"], ["\n"], ["qux\n"]]
p e.map {|ll| ll[0...-1].map {|l| l.sub(/\\\n\z/, "") }.join + ll.last }
#=>["foo\n", "barbaz\n", "\n", "qux\n"]

Calls:

parse(File.read(path), opts)

See method parse.

Calls:

JSON.parse!(File.read(path, opts))

See method parse!

Returns the Ruby objects created by parsing the given source.

BEWARE: This method is meant to serialise data from trusted user input, like from your own database server or clients under your control, it could be dangerous to allow untrusted users to pass JSON sources into it.


When no proc is given, modifies source as above and returns the result of parse(source, opts); see parse.

Source for following examples:

source = <<~JSON
  {
    "name": "Dave",
    "age" :40,
    "hats": [
      "Cattleman's",
      "Panama",
      "Tophat"
    ]
  }
JSON

Load a String:

ruby = JSON.unsafe_load(source)
ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}

Load an IO object:

require 'stringio'
object = JSON.unsafe_load(StringIO.new(source))
object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}

Load a File object:

path = 't.json'
File.write(path, source)
File.open(path) do |file|
  JSON.unsafe_load(file)
end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]}

When proc is given:

Example:

require 'json'

# Some classes for the example.
class Base
  def initialize(attributes)
    @attributes = attributes
  end
end
class User    < Base; end
class Account < Base; end
class Admin   < Base; end
# The JSON source.
json = <<-EOF
{
  "users": [
      {"type": "User", "username": "jane", "email": "jane@example.com"},
      {"type": "User", "username": "john", "email": "john@example.com"}
  ],
  "accounts": [
      {"account": {"type": "Account", "paid": true, "account_id": "1234"}},
      {"account": {"type": "Account", "paid": false, "account_id": "1235"}}
  ],
  "admins": {"type": "Admin", "password": "0wn3d"}
}
EOF
# Deserializer method.
def deserialize_obj(obj, safe_types = %w(User Account Admin))
  type = obj.is_a?(Hash) && obj["type"]
  safe_types.include?(type) ? Object.const_get(type).new(obj) : obj
end
# Call to JSON.unsafe_load
ruby = JSON.unsafe_load(json, proc {|obj|
  case obj
  when Hash
    obj.each {|k, v| obj[k] = deserialize_obj v }
  when Array
    obj.map! {|v| deserialize_obj v }
  end
})
pp ruby

Output:

{"users"=>
   [#<User:0x00000000064c4c98
     @attributes=
       {"type"=>"User", "username"=>"jane", "email"=>"jane@example.com"}>,
     #<User:0x00000000064c4bd0
     @attributes=
       {"type"=>"User", "username"=>"john", "email"=>"john@example.com"}>],
 "accounts"=>
   [{"account"=>
       #<Account:0x00000000064c4928
       @attributes={"type"=>"Account", "paid"=>true, "account_id"=>"1234"}>},
    {"account"=>
       #<Account:0x00000000064c4680
       @attributes={"type"=>"Account", "paid"=>false, "account_id"=>"1235"}>}],
 "admins"=>
   #<Admin:0x00000000064c41f8
   @attributes={"type"=>"Admin", "password"=>"0wn3d"}>}

Enters exclusive section.

Search took: 3ms  ·  Total Results: 2090