Class: Net::IMAP::Config

Inherits:
Object
  • Object
show all
Extended by:
AttrVersionDefaults
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,
lib/net/imap/config/attr_version_defaults.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  # => :frozen_dup

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 disable all currently deprecated behavior:

client = Net::IMAP.new(hostname, config: :future)
client.config.response_without_args     # => :frozen_dup
client.responses.frozen?                # => true
client.responses.values.all?(&:frozen?) # => true

Thread Safety

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

What's here?

Config attributes

Timeouts and other limits

  • #open_timeout: seconds to wait for connection to open or start TLS
  • #idle_response_timeout: seconds to wait for IDLE command to complete
  • max_response_size: Maximum allowed server response size.

Server capabilities

  • #sasl_ir: Controls SASL-IR behavior for Net::IMAP#authenticate.
  • #enforce_logindisabled: Controls LOGINDISABLED behavior in Net::IMAP#login.
  • max_non_synchronizing_literal: maximum bytesize for LITERAL+ / LITERAL- non-synchronizing literals.

Inherited defaults

Versioned defaults inherit these from ::global and #load_defaults doesn't update them.

  • #debug (aliased as #debug?): whether debug mode is enabled

Backward compatibility

These attributes will be removed by some future release.

  • #responses_without_block: Controls the behavior of Net::IMAP#responses when called without any arguments (+type+ or block).
  • #parser_use_deprecated_uidplus_data: Ignored since v0.6.0.
  • #parser_max_deprecated_uidplus_data_size: Ignored since v0.6.0.

Getting a new or existing config

  • ::global: The global config, used as the default #parent.
  • ::default: The hardcoded frozen default config, and parent of ::global.
  • ::version_defaults: Hard-coded frozen default configurations, indexed by version.
  • ::[]: Returns a config from ::version_defaults or created by ::new.
  • ::new: Return a new Config which inherits from a given parent.
  • #new: Return a new Config which inherits from self.

Updating multiple attributes

  • #load_defaults: Sets attributes to a given +version+'s default values.
  • #update: Assigns multiple attribute values to self.
  • #reset: Resets attributes to inherit from #parent.

Exporting multiple attributes

  • #to_h: Return a hash with all attributes.
  • #inspect (aliased as #to_s): Returns a string representation of overriden config attributes and the config inheritance chain.
  • #pretty_print: Used by PP to create a string representation of all config attributes and the inheritance chain.

Inheritance inspection

  • #parent: Returns the parent config object.
  • #inherited?: Returns whether all attributes inherit from #parent.
  • #inherits_defaults?: Returns whether all attributes inherit from a default config.
  • #overrides?: Returns whether any attributes override the #parent value.

Defined Under Namespace

Modules: AttrAccessors, AttrInheritance, AttrTypeCoercion, AttrVersionDefaults

Constant Summary

Constants included from AttrVersionDefaults

AttrVersionDefaults::CURRENT_VERSION, AttrVersionDefaults::NEXT_VERSION, AttrVersionDefaults::VERSIONS

Constants included from AttrTypeCoercion

AttrTypeCoercion::Enum, AttrTypeCoercion::NilOrInteger, AttrTypeCoercion::Types

Instance Attribute Summary

Attributes included from AttrVersionDefaults

#version_defaults

Attributes included from AttrInheritance

#parent

Attributes included from AttrAccessors

#attributes

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AttrVersionDefaults

attr_accessor, compile_default!, compile_version_defaults!

Methods included from AttrTypeCoercion

attr_accessor

Methods included from AttrInheritance

attr_accessor, #inherited?, #inherits_defaults?, #new, #overrides?, #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:



526
527
528
529
530
# File 'lib/net/imap/config.rb', line 526

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 -> versioned config Net::IMAP::Config -> named config Net::IMAP::Config -> new frozen config Net::IMAP::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.



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/net/imap/config.rb', line 223

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[config] or
      case config
      when Numeric
        raise RangeError, "unknown config version: %p" % [config]
      when String, Symbol
        raise KeyError, "unknown config name: %p" % [config]
      else
        raise TypeError, "no implicit conversion of %s to %s" % [
          config.class, Config
        ]
      end
  end
end

.default ⇒ Object

The default config, which is hardcoded and frozen.



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

def self.default; @default end

.global ⇒ Object

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



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

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

.version_defaults ⇒ Object

A hash of hard-coded configurations, indexed by version number or name. Values can be accessed with any object that responds to to_sym or +to_r+/+to_f+ with a non-zero number.

Config::[] gets named or numbered versions from this hash.

For example: Net::IMAP::Config.version_defaults == Net::IMAP::Config Net::IMAP::Config == Net::IMAP::Config # => true Net::IMAP::Config == Net::IMAP::Config # => true Net::IMAP::Config == Net::IMAP::Config # => true



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

def self.version_defaults; AttrVersionDefaults.version_defaults end

Instance Method Details

#inspect ⇒ Object Also known as: to_s

Returns a string representation of overriden config attributes and the inheritance chain.

Attributes overridden by ancestors are also inspected, recursively. Attributes that are inherited from default configs are not shown (see Config@Versioned+defaults and Config@Named+defaults).

# (Line breaks have been added to the example output for legibility.)

Net::IMAP::Config.new(0.4)
  .new(open_timeout: 10, enforce_logindisabled: true)
  .inspect
#=> "#<Net::IMAP::Config:0x0000745871125410 open_timeout=10 enforce_logindisabled=true
#      inherits from Net::IMAP::Config[0.4]
#      inherits from Net::IMAP::Config.global
#      inherits from Net::IMAP::Config.default>"

Non-default attributes are listed after the ancestor config from which they are inherited.

# (Line breaks have been added to the example output for legibility.)

config = Net::IMAP::Config.global
  .new(open_timeout: 10, idle_response_timeout: 2)
  .new(enforce_logindisabled: :when_capabilities_cached, sasl_ir: false)
config.inspect
#=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
#      inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
#      inherits from Net::IMAP::Config.global
#      inherits from Net::IMAP::Config.default>"

Net::IMAP.debug = true
config.inspect
#=> "#<Net::IMAP::Config:0x00007ce2a1e20e40 sasl_ir=false enforce_logindisabled=:when_capabilities_cached
#      inherits from Net::IMAP::Config:0x00007ce2a1e20f80 open_timeout=10 idle_response_timeout=2
#      inherits from Net::IMAP::Config.global debug=true
#      inherits from Net::IMAP::Config.default>"

Use pp (see #pretty_print) to inspect all config attributes, including default values.

Use #to_h to inspect all config attributes ignoring inheritance.



630
631
632
# File 'lib/net/imap/config.rb', line 630

def inspect;
  "#<#{inspect_recursive}>"
end

#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.



577
578
579
580
581
# File 'lib/net/imap/config.rb', line 577

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

#pretty_print(pp) ⇒ Object

Used by PP to create a string representation of all config attributes and the inheritance chain. Inherited attributes are listed with the ancestor config from which they are inherited.

pp Config.new[0.4].new(open_timeout: 10, idle_response_timeout: 10)
# #<Net::IMAP::Config:0x0000745871125410
#   open_timeout=10
#   idle_response_timeout=10
#   inherits from Net::IMAP::Config[0.4]
#     responses_without_block=:silence_deprecation_warning
#     max_response_size=nil
#     sasl_ir=true
#     enforce_logindisabled=false
#     parser_use_deprecated_uidplus_data=true
#     parser_max_deprecated_uidplus_data_size=1000
#     inherits from Net::IMAP::Config.global
#       inherits from Net::IMAP::Config.default
#         debug=false>

Related: #inspect, #to_h.



656
657
658
659
660
# File 'lib/net/imap/config.rb', line 656

def pretty_print(pp)
  pp.group(2, "#<", ">") do
    pretty_print_recursive(pp)
  end
end

#to_h ⇒ Object

:call-seq: to_h -> hash

Returns all config attributes in a hash.



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

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.



542
543
544
545
546
547
548
# File 'lib/net/imap/config.rb', line 542

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.



560
561
562
563
564
565
566
# File 'lib/net/imap/config.rb', line 560

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