Class: Net::IMAP::Config

Inherits:
Object
  • Object
show all
Includes:
AttrAccessors, AttrInheritance, AttrTypeCoercion
Defined in:
lib/net/imap/config.rb,
lib/net/imap/config/attr_accessors.rb,
lib/net/imap/config/attr_inheritance.rb,
lib/net/imap/config/attr_type_coercion.rb

Overview

Net::IMAP::Config (available since v0.4.13) stores configuration options for Net::IMAP clients. The global configuration can be seen at either Net::IMAP.config or Net::IMAP::Config.global, and the client-specific configuration can be seen at Net::IMAP#config.

When creating a new client, all unhandled keyword arguments to Net::IMAP.new are delegated to Config.new. Every client has its own config.

debug_client = Net::IMAP.new(hostname, debug: true)
quiet_client = Net::IMAP.new(hostname, debug: false)
debug_client.config.debug?  # => true
quiet_client.config.debug?  # => false

Inheritance

Configs have a parent config, and any attributes which have not been set locally will inherit the parent’s value. Every client creates its own specific config. By default, client configs inherit from Config.global.

plain_client = Net::IMAP.new(hostname)
debug_client = Net::IMAP.new(hostname, debug: true)
quiet_client = Net::IMAP.new(hostname, debug: false)

plain_client.config.inherited?(:debug)  # => true
debug_client.config.inherited?(:debug)  # => false
quiet_client.config.inherited?(:debug)  # => false

plain_client.config.debug?  # => false
debug_client.config.debug?  # => true
quiet_client.config.debug?  # => false

# Net::IMAP.debug is delegated to Net::IMAP::Config.global.debug
Net::IMAP.debug = true
plain_client.config.debug?  # => true
debug_client.config.debug?  # => true
quiet_client.config.debug?  # => false

Net::IMAP.debug = false
plain_client.config.debug = true
plain_client.config.inherited?(:debug)  # => false
plain_client.config.debug?  # => true
plain_client.config.reset(:debug)
plain_client.config.inherited?(:debug)  # => true
plain_client.config.debug?  # => false

Versioned defaults

The effective default configuration for a specific x.y version of net-imap can be loaded with the config keyword argument to Net::IMAP.new. Requesting default configurations for previous versions enables extra backward compatibility with those versions:

client = Net::IMAP.new(hostname, config: 0.3)
client.config.sasl_ir                  # => false
client.config.responses_without_block  # => :silence_deprecation_warning

client = Net::IMAP.new(hostname, config: 0.4)
client.config.sasl_ir                  # => true
client.config.responses_without_block  # => :silence_deprecation_warning

client = Net::IMAP.new(hostname, config: 0.5)
client.config.sasl_ir                  # => true
client.config.responses_without_block  # => :warn

client = Net::IMAP.new(hostname, config: :future)
client.config.sasl_ir                  # => true
client.config.responses_without_block  # => :raise

The versioned default configs inherit certain specific config options from Config.global, for example #debug:

client = Net::IMAP.new(hostname, config: 0.4)
Net::IMAP.debug = false
client.config.debug?  # => false

Net::IMAP.debug = true
client.config.debug?  # => true

Use #load_defaults to globally behave like a specific version:

client = Net::IMAP.new(hostname)
client.config.sasl_ir              # => true
Net::IMAP.config.load_defaults 0.3
client.config.sasl_ir              # => false

Named defaults

In addition to x.y version numbers, the following aliases are supported:

:default

An alias for :current.

NOTE: This is not the same as Config.default. It inherits some attributes from Config.global, for example: #debug.

:current

An alias for the current x.y version’s defaults.

:next

The planned config for the next x.y version.

:future

The planned eventual config for some future x.y version.

For example, to raise exceptions for all current deprecations:

client = Net::IMAP.new(hostname, config: :future)
client.responses  # raises an ArgumentError

Thread Safety

NOTE: Updates to config objects are not synchronized for thread-safety.

Defined Under Namespace

Modules: AttrAccessors, AttrInheritance, AttrTypeCoercion

Instance Attribute Summary

Attributes included from AttrInheritance

#parent

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AttrTypeCoercion

attr_accessor, boolean, enum, integer

Methods included from AttrInheritance

attr_accessor, #inherited?, #new, #reset

Methods included from AttrAccessors

attr_accessor, #freeze, struct

Constructor Details

#initialize(parent = Config.global, **attrs) {|_self| ... } ⇒ Config

Creates a new config object and initialize its attribute with attrs.

If parent is not given, the global config is used by default.

If a block is given, the new config object is yielded to it.

Yields:

  • (_self)

Yield Parameters:



293
294
295
296
297
# File 'lib/net/imap/config.rb', line 293

def initialize(parent = Config.global, **attrs)
  super(parent)
  update(**attrs)
  yield self if block_given?
end

Class Method Details

.[](config) ⇒ Object

:call-seq:

Net::IMAP::Config[number] -> versioned config
Net::IMAP::Config[symbol] -> named config
Net::IMAP::Config[hash]   -> new frozen config
Net::IMAP::Config[config] -> same config

Given a version number, returns the default configuration for the target version. See Config@Versioned+defaults.

Given a version name, returns the default configuration for the target version. See Config@Named+defaults.

Given a Hash, creates a new frozen config which inherits from Config.global. Use Config.new for an unfrozen config.

Given a config, returns that same config.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/net/imap/config.rb', line 151

def self.[](config)
  if    config.is_a?(Config)         then config
  elsif config.nil? && global.nil?   then nil
  elsif config.respond_to?(:to_hash) then new(global, **config).freeze
  else
    version_defaults.fetch(config) do
      case config
      when Numeric
        raise RangeError, "unknown config version: %p" % [config]
      when Symbol
        raise KeyError, "unknown config name: %p" % [config]
      else
        raise TypeError, "no implicit conversion of %s to %s" % [
          config.class, Config
        ]
      end
    end
  end
end

.defaultObject

The default config, which is hardcoded and frozen.



126
# File 'lib/net/imap/config.rb', line 126

def self.default; @default end

.globalObject

The global config object. Also available from Net::IMAP.config.



129
# File 'lib/net/imap/config.rb', line 129

def self.global; @global if defined?(@global) end

.version_defaultsObject

A hash of hard-coded configurations, indexed by version number or name.



132
# File 'lib/net/imap/config.rb', line 132

def self.version_defaults; @version_defaults end

Instance Method Details

#load_defaults(version) ⇒ Object

:call-seq: load_defaults(version) -> self

Resets the current config to behave like the versioned default configuration for version. #parent will not be changed.

Some config attributes default to inheriting from their #parent (which is usually Config.global) and are left unchanged, for example: #debug.

See Config@Versioned+defaults and Config@Named+defaults.



344
345
346
347
348
# File 'lib/net/imap/config.rb', line 344

def load_defaults(version)
  [Numeric, Symbol, String].any? { _1 === version } or
    raise ArgumentError, "expected number or symbol, got %p" % [version]
  update(**Config[version].defaults_hash)
end

#to_hObject

:call-seq: to_h -> hash

Returns all config attributes in a hash.



353
# File 'lib/net/imap/config.rb', line 353

def to_h; data.members.to_h { [_1, send(_1)] } end

#update(**attrs) ⇒ Object

:call-seq: update(**attrs) -> self

Assigns all of the provided attrs to this config, and returns self.

An ArgumentError is raised unless every key in attrs matches an assignment method on Config.

NOTE: #update is not atomic. If an exception is raised due to an invalid attribute value, attrs may be partially applied.



309
310
311
312
313
314
315
# File 'lib/net/imap/config.rb', line 309

def update(**attrs)
  unless (bad = attrs.keys.reject { respond_to?(:"#{_1}=") }).empty?
    raise ArgumentError, "invalid config options: #{bad.join(", ")}"
  end
  attrs.each do send(:"#{_1}=", _2) end
  self
end

#with(**attrs) ⇒ Object

:call-seq:

with(**attrs) -> config
with(**attrs) {|config| } -> result

Without a block, returns a new config which inherits from self. With a block, yields the new config and returns the block’s result.

If no keyword arguments are given, an ArgumentError will be raised.

If self is frozen, the copy will also be frozen.



327
328
329
330
331
332
333
# File 'lib/net/imap/config.rb', line 327

def with(**attrs)
  attrs.empty? and
    raise ArgumentError, "expected keyword arguments, none given"
  copy = new(**attrs)
  copy.freeze if frozen?
  block_given? ? yield(copy) : copy
end