Results for: "Array"

This class is useful for exploring contents before and after a block

It searches above and below the passed in block to match for whatever criteria you give it:

Example:

def dog         # 1
  puts "bark"   # 2
  puts "bark"   # 3
end             # 4

scan = AroundBlockScan.new(
  code_lines: code_lines
  block: CodeBlock.new(lines: code_lines[1])
)

scan.scan_while { true }

puts scan.before_index # => 0
puts scan.after_index  # => 3

Searches code for a syntax error

There are three main phases in the algorithm:

  1. Sanitize/format input source

  2. Search for invalid blocks

  3. Format invalid blocks into something meaninful

This class handles the part.

The bulk of the heavy lifting is done in:

- CodeFrontier (Holds information for generating blocks and determining if we can stop searching)
- ParseBlocksFromLine (Creates blocks into the frontier)
- BlockExpand (Expands existing blocks to search more code)

## Syntax error detection

When the frontier holds the syntax error, we can stop searching

search = CodeSearch.new(<<~EOM)
  def dog
    def lol
  end
EOM

search.call

search.invalid_blocks.map(&:to_s) # =>
# => ["def lol\n"]

Outputs code with highlighted lines

Whatever is passed to this class will be rendered even if it is “marked invisible” any filtering of output should be done before calling this class.

DisplayCodeWithLineNumbers.new(
  lines: lines,
  highlight_lines: [lines[2], lines[3]]
).call
# =>
    1
    2  def cat
  > 3    Dir.chdir
  > 4    end
    5  end
    6

Used for formatting invalid blocks

This class is responsible for generating initial code blocks that will then later be expanded.

The biggest concern when guessing code blocks, is accidentally grabbing one that contains only an “end”. In this example:

def dog
  begonn # misspelled `begin`
  puts "bark"
  end
end

The following lines would be matched (from bottom to top):

1) end

2) puts "bark"
   end

3) begonn
   puts "bark"
   end

At this point it has no where else to expand, and it will yield this inner code as a block

Capture parse errors from Ripper

Prism returns the errors with their messages, but Ripper does not. To get them we must make a custom subclass.

Example:

puts RipperErrors.new(" def foo").call.errors
# => ["syntax error, unexpected end-of-input, expecting ';' or '\\n'"]

Raised by Timeout.timeout when the block times out.

Base class for all URI exceptions.

Not a URI.

Not a URI component.

URI is valid, bad usage is not.

RefError is raised when a referenced object has been recycled by the garbage collector

Raised when a mathematical function is evaluated outside of its domain of definition.

For example, since cos returns values in the range -1..1, its inverse function acos is only defined on that interval:

Math.acos(42)

produces:

Math::DomainError: Numerical argument is out of domain - "acos"
No documentation available
No documentation available

Raised on attempt to Ractor#take if there was an uncaught exception in the Ractor. Its cause will contain the original exception, and ractor is the original ractor it was raised in.

r = Ractor.new { raise "Something weird happened" }

begin
  r.take
rescue => e
  p e             # => #<Ractor::RemoteError: thrown by remote Ractor.>
  p e.ractor == r # => true
  p e.cause       # => #<RuntimeError: Something weird happened>
end

Raised on an attempt to access an object which was moved in Ractor#send or Ractor.yield.

r = Ractor.new { sleep }

ary = [1, 2, 3]
r.send(ary, move: true)
ary.inspect
# Ractor::MovedError (can not send any methods to a moved object)

Raised when an attempt is made to send a message to a closed port, or to retrieve a message from a closed and empty port. Ports may be closed explicitly with Ractor#close_outgoing/close_incoming and are closed implicitly when a Ractor terminates.

r = Ractor.new { sleep(500) }
r.close_outgoing
r.take # Ractor::ClosedError

ClosedError is a descendant of StopIteration, so the closing of the ractor will break the loops without propagating the error:

r = Ractor.new do
  loop do
    msg = receive # raises ClosedError and loop traps it
    puts "Received: #{msg}"
  end
  puts "loop exited"
end

3.times{|i| r << i}
r.close_incoming
r.take
puts "Continue successfully"

This will print:

Received: 0
Received: 1
Received: 2
loop exited
Continue successfully
No documentation available
No documentation available

ConditionVariable objects augment class Mutex. Using condition variables, it is possible to suspend while in the middle of a critical section until a condition is met, such as a resource becomes available.

Due to non-deterministic scheduling and spurious wake-ups, users of condition variables should always use a separate boolean predicate (such as reading from a boolean variable) to check if the condition is actually met before starting to wait, and should wait in a loop, re-checking the condition every time the ConditionVariable is waken up. The idiomatic way of using condition variables is calling the wait method in an until loop with the predicate as the loop condition.

condvar.wait(mutex) until condition_is_met

In the example below, we use the boolean variable resource_available (which is protected by mutex) to indicate the availability of the resource, and use condvar to wait for that variable to become true. Note that:

  1. Thread b may be scheduled before thread a1 and a2, and may run so fast that it have already made the resource available before either a1 or a2 starts. Therefore, a1 and a2 should check if resource_available is already true before starting to wait.

  2. The wait method may spuriously wake up without signalling. Therefore, thread a1 and a2 should recheck resource_available after the wait method returns, and go back to wait if the condition is not actually met.

  3. It is possible that thread a2 starts right after thread a1 is waken up by b. Thread a2 may have acquired the mutex and consumed the resource before thread a1 acquires the mutex. This necessitates rechecking after wait, too.

Example:

mutex = Thread::Mutex.new

resource_available = false
condvar = Thread::ConditionVariable.new

a1 = Thread.new {
  # Thread 'a1' waits for the resource to become available and consumes
  # the resource.
  mutex.synchronize {
    condvar.wait(mutex) until resource_available
    # After the loop, 'resource_available' is guaranteed to be true.

    resource_available = false
    puts "a1 consumed the resource"
  }
}

a2 = Thread.new {
  # Thread 'a2' behaves like 'a1'.
  mutex.synchronize {
    condvar.wait(mutex) until resource_available
    resource_available = false
    puts "a2 consumed the resource"
  }
}

b = Thread.new {
  # Thread 'b' periodically makes the resource available.
  loop {
    mutex.synchronize {
      resource_available = true

      # Notify one waiting thread if any.  It is possible that neither
      # 'a1' nor 'a2 is waiting on 'condvar' at this moment.  That's OK.
      condvar.signal
    }
    sleep 1
  }
}

# Eventually both 'a1' and 'a2' will have their resources, albeit in an
# unspecified order.
[a1, a2].each {|th| th.join}

Raised by Encoding and String methods when a transcoding operation fails.

Raised by Encoding and String methods when the string being transcoded contains a byte invalid for the either the source or target encoding.

Raised by transcoding methods when a named encoding does not correspond with a known converter.

An internal representation of the backtrace. The user will never interact with objects of this class directly, but class methods can be used to get backtrace settings of the current session.

Search took: 4ms  ·  Total Results: 1476