Results for: "remove_const"

Mixin methods for local and remote Gem::Command options.

No documentation available
No documentation available
No documentation available
No documentation available

This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified.

# shareable_constant_value: literal
C = { a: 1 }
^^^^^^^^^^^^

Flags for shareable constant nodes.

Represents a regular expression literal that contains interpolation.

/foo #{bar} baz/
^^^^^^^^^^^^^^^^

Represents a regular expression literal with no interpolation.

/foo/i
^^^^^^

Represents an error communicating via HTTP.

Flags for regular expression and match last line nodes.

Raised by exit to initiate the termination of the script.

SystemCallError is the base class for all low-level platform-dependent errors.

The errors available on the current platform are subclasses of SystemCallError and are defined in the Errno module.

File.open("does/not/exist")

raises the exception:

Errno::ENOENT: No such file or directory - does/not/exist

Use the Monitor class when you want to have a lock object for blocks with mutual exclusion.

require 'monitor'

lock = Monitor.new
lock.synchronize do
  # exclusive access
end

PStore implements a file based persistence mechanism based on a Hash. User code can store hierarchies of Ruby objects (values) into the data store by name (keys). An object hierarchy may be just a single object. User code may later read values back from the data store or even update data, as needed.

The transactional behavior ensures that any changes succeed or fail together. This can be used to ensure that the data store is not left in a transitory state, where some values were updated but others were not.

Behind the scenes, Ruby objects are stored to the data store file with Marshal. That carries the usual limitations. Proc objects cannot be marshalled, for example.

There are three important concepts here (details at the links):

About the Examples

Examples on this page need a store that has known properties. They can get a new (and populated) store by calling thus:

example_store do |store|
  # Example code using store goes here.
end

All we really need to know about example_store is that it yields a fresh store with a known population of entries; its implementation:

require 'pstore'
require 'tempfile'
# Yield a pristine store for use in examples.
def example_store
  # Create the store in a temporary file.
  Tempfile.create do |file|
    store = PStore.new(file)
    # Populate the store.
    store.transaction do
      store[:foo] = 0
      store[:bar] = 1
      store[:baz] = 2
    end
    yield store
  end
end

The Store

The contents of the store are maintained in a file whose path is specified when the store is created (see PStore.new). The objects are stored and retrieved using module Marshal, which means that certain objects cannot be added to the store; see Marshal::dump.

Entries

A store may have any number of entries. Each entry has a key and a value, just as in a hash:

Transactions

The Transaction Block

The block given with a call to method transaction# contains a transaction, which consists of calls to PStore methods that read from or write to the store (that is, all PStore methods except transaction itself, path, and Pstore.new):

example_store do |store|
  store.transaction do
    store.keys # => [:foo, :bar, :baz]
    store[:bat] = 3
    store.keys # => [:foo, :bar, :baz, :bat]
  end
end

Execution of the transaction is deferred until the block exits, and is executed atomically (all-or-nothing): either all transaction calls are executed, or none are. This maintains the integrity of the store.

Other code in the block (including even calls to path and PStore.new) is executed immediately, not deferred.

The transaction block:

As seen above, changes in a transaction are made automatically when the block exits. The block may be exited early by calling method commit or abort.

Read-Only Transactions

By default, a transaction allows both reading from and writing to the store:

store.transaction do
  # Read-write transaction.
  # Any code except a call to #transaction is allowed here.
end

If argument read_only is passed as true, only reading is allowed:

store.transaction(true) do
  # Read-only transaction:
  # Calls to #transaction, #[]=, and #delete are not allowed here.
end

Hierarchical Values

The value for an entry may be a simple object (as seen above). It may also be a hierarchy of objects nested to any depth:

deep_store = PStore.new('deep.store')
deep_store.transaction do
  array_of_hashes = [{}, {}, {}]
  deep_store[:array_of_hashes] = array_of_hashes
  deep_store[:array_of_hashes] # => [{}, {}, {}]
  hash_of_arrays = {foo: [], bar: [], baz: []}
  deep_store[:hash_of_arrays] = hash_of_arrays
  deep_store[:hash_of_arrays]  # => {:foo=>[], :bar=>[], :baz=>[]}
  deep_store[:hash_of_arrays][:foo].push(:bat)
  deep_store[:hash_of_arrays]  # => {:foo=>[:bat], :bar=>[], :baz=>[]}
end

And recall that you can use dig methods in a returned hierarchy of objects.

Working with the Store

Creating a Store

Use method PStore.new to create a store. The new store creates or opens its containing file:

store = PStore.new('t.store')

Modifying the Store

Use method []= to update or create an entry:

example_store do |store|
  store.transaction do
    store[:foo] = 1 # Update.
    store[:bam] = 1 # Create.
  end
end

Use method delete to remove an entry:

example_store do |store|
  store.transaction do
    store.delete(:foo)
    store[:foo] # => nil
  end
end

Retrieving Values

Use method fetch (allows default) or [] (defaults to nil) to retrieve an entry:

example_store do |store|
  store.transaction do
    store[:foo]             # => 0
    store[:nope]            # => nil
    store.fetch(:baz)       # => 2
    store.fetch(:nope, nil) # => nil
    store.fetch(:nope)      # Raises exception.
  end
end

Querying the Store

Use method key? to determine whether a given key exists:

example_store do |store|
  store.transaction do
    store.key?(:foo) # => true
  end
end

Use method keys to retrieve keys:

example_store do |store|
  store.transaction do
    store.keys # => [:foo, :bar, :baz]
  end
end

Use method path to retrieve the path to the store’s underlying file; this method may be called from outside a transaction block:

store = PStore.new('t.store')
store.path # => "t.store"

Transaction Safety

For transaction safety, see:

Needless to say, if you’re storing valuable data with PStore, then you should backup the PStore file from time to time.

An Example Store

require "pstore"

# A mock wiki object.
class WikiPage

  attr_reader :page_name

  def initialize(page_name, author, contents)
    @page_name = page_name
    @revisions = Array.new
    add_revision(author, contents)
  end

  def add_revision(author, contents)
    @revisions << {created: Time.now,
                   author: author,
                   contents: contents}
  end

  def wiki_page_references
    [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
  end

end

# Create a new wiki page.
home_page = WikiPage.new("HomePage", "James Edward Gray II",
                         "A page about the JoysOfDocumentation..." )

wiki = PStore.new("wiki_pages.pstore")
# Update page data and the index together, or not at all.
wiki.transaction do
  # Store page.
  wiki[home_page.page_name] = home_page
  # Create page index.
  wiki[:wiki_index] ||= Array.new
  # Update wiki index.
  wiki[:wiki_index].push(*home_page.wiki_page_references)
end

# Read wiki data, setting argument read_only to true.
wiki.transaction(true) do
  wiki.keys.each do |key|
    puts key
    puts wiki[key]
  end
end

In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. The defining characteristic of a monitor is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods. This mutual exclusion greatly simplifies reasoning about the implementation of monitors compared to reasoning about parallel code that updates a data structure.

You can read more about the general principles on the Wikipedia page for Monitors.

Examples

Simple object.extend

require 'monitor.rb'

buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond

# consumer
Thread.start do
  loop do
    buf.synchronize do
      empty_cond.wait_while { buf.empty? }
      print buf.shift
    end
  end
end

# producer
while line = ARGF.gets
  buf.synchronize do
    buf.push(line)
    empty_cond.signal
  end
end

The consumer thread waits for the producer thread to push a line to buf while buf.empty?. The producer thread (main thread) reads a line from ARGF and pushes it into buf then calls empty_cond.signal to notify the consumer thread of new data.

Simple Class include

require 'monitor'

class SynchronizedArray < Array

  include MonitorMixin

  def initialize(*args)
    super(*args)
  end

  alias :old_shift :shift
  alias :old_unshift :unshift

  def shift(n=1)
    self.synchronize do
      self.old_shift(n)
    end
  end

  def unshift(item)
    self.synchronize do
      self.old_unshift(item)
    end
  end

  # other methods ...
end

SynchronizedArray implements an Array with synchronized access to items. This Class is implemented as subclass of Array which includes the MonitorMixin module.

Response class for Precondition Failed responses (status code 412).

The server does not meet one of the preconditions specified in the request headers.

References:

Turns a “invalid block(s)” into useful context

There are three main phases in the algorithm:

  1. Sanitize/format input source

  2. Search for invalid blocks

  3. Format invalid blocks into something meaningful

This class handles the third part.

The algorithm is very good at capturing all of a syntax error in a single block in number 2, however the results can contain ambiguities. Humans are good at pattern matching and filtering and can mentally remove extraneous data, but they can’t add extra data that’s not present.

In the case of known ambiguious cases, this class adds context back to the ambiguity so the programmer has full information.

Beyond handling these ambiguities, it also captures surrounding code context information:

puts block.to_s # => "def bark"

context = CaptureCodeContext.new(
  blocks: block,
  code_lines: code_lines
)

lines = context.call.map(&:original)
puts lines.join
# =>
  class Dog
    def bark
  end

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

No documentation available

Parent class for redirection (3xx) HTTP response classes.

A redirection response indicates the client must take additional action to complete the request.

References:

Response class for Proxy Authentication Required responses (status code 407).

The client must first authenticate itself with the proxy.

References:

Response class for Misdirected Request responses (status code 421).

The request was directed at a server that is not able to produce a response.

References:

Response class for Network Authentication Required responses (status code 511).

The client needs to authenticate to gain network access.

References:

Represents an interpolated set of statements.

"foo #{bar}"
     ^^^^^^
Search took: 11ms  ·  Total Results: 5438