Matty's Ultimate Gem

Gem Version
Hound-CI
Contributor Covenant

alias

Module

alias_singleton_method(new_name, old_name) => self

Makes new_name a new copy of the instance method old_name. This can be used to retain access to instance methods that are overridden.

Examples

require 'mug/alias'

module Mod
  def self.foo
    1
  end
  alias_singleton_method :bar, :foo
  def self.foo
    2
  end
end
Mod.foo #=> 2
Mod.bar #=> 1

and-or

Object

obj.and default
obj.and default {|o| block }

Returns either obj or default, depending on the falsiness of obj.

If a block is given, obj is yielded to it; if it returns truthy, default is returned, otherwise obj is returned.

obj.or default
obj.or default {|o| block }

Returns either obj or default, depending on the truthiness of obj.

If a block is given, obj is yielded to it; if it returns truthy, obj is returned, otherwise default is returned.

obj.and_then {|o| block }

Calls block if obj is truthy.

Returns obj.

obj.or_then {|o| block }

Calls block if obj is falsey.

Returns obj.

Examples

require 'mug/and-or'

data_store.get_env_hash.or(default_hash).do_something

get_a_list.and(default_list, &:empty?).do_something

try_thing.and_then {|result| log "got #{result.inspect}" }
try_thing.or_then { log "failed" }

apply

Proc

proc.apply *args

Curries this Proc and partially applies parameters.
If a sufficient number of arguments are supplied, it passes the
supplied arguments to the original proc and returns the result.
Otherwise, returns another curried proc that takes the rest of
arguments.

Method

meth.curry
meth.curry n

Returns a curried proc. If the optional arity argument is given,
it determines the number of arguments. A curried proc receives
some arguments. If a sufficient number of arguments are supplied,
it passes the supplied arguments to the original proc and returns
the result. Otherwise, returns another curried proc that takes the
rest of arguments.

meth.apply *args

Curries this Method and partially applies parameters.
If a sufficient number of arguments are supplied, it passes the
supplied arguments to the original proc and returns the result.
Otherwise, returns another curried proc that takes the rest of
arguments.

array/delete_all

Array

array.delete_all {|item| block } => array
array.delete_all => Enumerator

Deletes every element of self for which block evaluates to true.

Returns an array of the deleted elements.

If no block is given, an Enumerator is returned instead.

See #delete_if, #reject!

Feature #13777

array/extend

Array

array.extend!(size=0, obj=nil)
array.extend!(array)
array.extend!(size) {|index| block }

Extend this Array.

In the first form, when a size and an optional obj are sent,
the array is extended with size copies of obj. Take notice that
all elements will reference the same object obj.

The second form appends a copy of the array passed as a parameter
(the array is generated by calling #to_ary on the parameter).
See also: #concat, #+

In the last form, the array is extended by the given size. Each new
element in the array is created by passing the element's index to the
given block and storing the return value.

array.extend(size=0, obj=nil)
array.extend(array)
array.extend(size) {|index| block }

See #extend!

array/minus

Array

array.minus(ary, remainder: false)

Subtract elements from this array.

This is similar to Array#- except that elements from this array are
removed only once per instance in ary.

If remainder is given and true, returns a second array which is
all elements in ary that were not present in this array.

array ^ other

Get the elements unique to one of two arrays.

Duplicates in either array are included only once.

array/samples

Array

array.samples(min: int, max: int, random: rng) => new_ary

Choose a random subset of elements from the array.

The elements are chosen by using random and unique indices into the
array in order to ensure that an element doesn't repeat itself
unless the array already contained duplicate elements.

The optional min and max arguments restrict the size of the
returned array. min must be >= 0, and max must be >= min.
(Both values are clamped to the size of the array.)

If the array is empty, always returns an empty array.

The optional random argument will be used as the random number
generator.

array/to_proc

Array

array.to_proc => proc {|args..| ...}

Returns a Proc that accepts one or two arguments.

The Proc's parameter is used as an index into this array.

See: #slice

bittest

Integer

int.and?(other, test: :any)

Tests common bits in this AND other.

test:

int.and_any?(other)

True if this AND other is non-zero.

i.e. if any set bits in other are set in this.

int.and_all?(other)

True if this AND other is other.

i.e. if all set bits in other are set in this.

int.or?(other)

True if this OR other is non-zero.

int.xor?(other)

True if this XOR other is non-zero.

bool

Kernel

Bool(obj)

Returns the truthiness of obj, as either True or False.

This is functionally equivalent to calling !!obj

Object

obj.to_b

Converts obj to a boolean using "typical" C-like conversion rules.

The following values all become false:

All others values become true.

obj.to_bool

Returns the truthiness of obj, as either True or False.

This is functionally equivalent to calling !!obj

Examples

require 'mug/bool'

Bool(obj) #=> !!obj
obj.to_bool #=> !!obj
obj.to_b #=> C-like truthiness

clamp

Clamps a number to a range.

Numeric

num.clamp lower, higher => new_num

Clamps num so that lower <= new_num <= higher.

Returns lower when num < lower, higher when num > higher, otherwise
num itself.

Raises an exception if lower > higher

num.clamp range => new_num

Effectively calls range#bound

Range

rng.bound val => new_val

Bounds val so that first <= new_val <= last.

Returns first when val < first, last when val > last, otherwise
val itself.

Raises an exception if val >= end and the range is exclusive.

diggable

Implements #dig for any object that implements #[]

Diggable

Extend any class or object that implements a #[] method, to
also have #dig

diggy.dig *idx

Extracts the nested value specified by the sequence of idx objects by
calling dig at each step, returning nil if any intermediate step is
nil.

enumerable/any-and-all

Enumerable

enum.any_and_all? {|obj| block }

Passes each element of the collection to the given block. The method returns true if the
block contains elements that never return false or nil. If the block is not given, Ruby
adds an implicit block of { |obj| obj } which will cause any_and_all? to return true
when none of the collection members are false or nil.

enumerable/chain

Enumerable

Enumerable.chain(*enums)
Enumerable.chain(*enums) {|...| block }

Invokes a block once for every element in a sequence of
Enumerables.

WARNING: Enumerable\#chain defined since Ruby 2.6 is incompatible with this gem when used with args and a block

enum.chain(*enums)
enum.chain(*enums) {|...| block }

Creates a chain of Enumerables following this one, and
invokes a block once for each element of each Enumerable.

enumerable/counts

Returns counts of objects in enumerables.

Enumerable

enum.counts

Returns a hash of item=>count showing how many
of each item are in this Enumerable.

enum.counts_by {|item| block }

Passes each element in turn to the block, and returns a
hash of result=>count.

If no block is given, an enumerator is returned.

Examples

require 'mug/enumerable/counts'

%w(a b b).counts                   #=> {'a'=>1, 'b'=>2}
%w(a b b).counts_by{|o| o.upcase } #=> {'A'=>1, 'B'=>2}

enumerable/hash-like

Makes Enumerables quack a bit more like a hash. A lot of these will not work on indeterminate or
infinite sequences.

Enumerable

each_pair {| key, value | block } => hsh
each_pair => an_enumerator

Calls block once for each key in the enum, passing the key-value pair as parameters.
If no block is given, an enumerator is returned instead.

each_key {| key | block } => hsh
each_key => an_enumerator

Calls block once for each key in the enum, passing the key as a parameter.
If no block is given, an enumerator is returned instead.

fetch(key [, default] ) => obj
fetch(key) { |key| block } => obj

Returns a value from the enum for the given key. If the key can't be
found, there are several options: With no other arguments, it will
raise a KeyError exception; if default is given, then that will
be returned; if the optional code block is specified, then that will
be run and its result returned.

fetch_values(key, ...) => array
fetch_values(key, ...) { |key| block } => array

Returns an array containing the values associated with the given keys
but also raises KeyError when one of keys can't be found.
Also see #values_at and #fetch.

key?(key) => true or false

Returns true if the given key is present in this enum.

keys => array

Returns a new array populated with the keys from this enum.

length => integer

Returns the number of key-value pairs in the hash.

member?(key) => true or false

Returns true if the given key is present in this enum.

slice(*keys) => a_hash

Returns a hash containing only the given keys and their values.

transform_keys {|key| block } => new_hash
transform_keys => an_enumerator

Returns a new hash with the results of running the block once for every key.
If no block is given, an enumerator is returned instead.

transform_values {|value| block } => new_hash
transform_values => an_enumerator

Returns a new hash with the results of running the block once for every value.
If no block is given, an enumerator is returned instead.

value?(value) => true or false

Returns true if the given value is present for some key.

values => array

Returns a new array populated with the values from this enum.

values_at(key, ...) => array

Return an array containing the values associated with the given keys.

fragile-method-chain

Defines a fragile method chain. If any method call in the chain returns a falsy value, the chain aborts.

require 'mug/fragile-method-chain'

# Similar to: a.b && a.b.c
# except that a.b is not called twice
a._?.b.c._!

# Also works with #[] method
nested_hash._?[:a][:b][:c]._!

hash/fetch-assign

Hash

hsh.fetch_assign(key, default) => obj
hsh.fetch_assign(key) {|key| block } => obj

Returns a value from the hash for the given key. If the key can't be
found, there are several options: if default is given, then that will
be stored and returned; if the optional code block is specified, then
that will be run and its result stored and returned.

(#compute_if_absent is an alias of this method)

require 'mug/hash/fetch-assign'

hsh = {}

hsh.fetch_assign(:a, 1) # => 1
# hsh => {:a => 1}

hsh.fetch_assign(:a, 42) # => 1
# hsh => {:a => 1}

hsh.fetch_assign(:b) {|key| key.to_s } #=> "b"
# hsh => {:a => 1, :b => "b"}

hash/map

Hash

hsh.map_values {|v| block }

Returns a new hash which is a copy of hsh but each value is replaced by the result of running it through block.

As of Ruby 2.4 this is equivalent to #transform_values

require 'mug/hash/map'

{'a'=>1, 'b'=>2}.map_values { |v| v*2 } #=> {'a'=>2, 'b'=>4}
{'a'=>1, 'b'=>2}.map_values { "cat" }   #=> {'a'=>"cat", 'b'=>"cat"}

hsh.map_values! {|v| block }

Replaces the values in hsh by running them each through block.

As of Ruby 2.4 this is equivalent to #transform_values!

See: #map_values

hsh.map_keys {|k| block }

Returns a new hash which is a copy of hsh but each key is replaced by the result of running it through block.

If block returns duplicate keys, they will be overwritten in the resulting hash.

As of Ruby 2.5 this is equivalent to #transform_keys

require 'mug/hash/map'

{'a'=>1, 'b'=>2}.map_keys { |k| k*2 } #=> {'aa'=>1, 'bb'=>2}
{'a'=>1, 'b'=>2}.map_keys { "cat" }   #=> {'cat'=>2}

hsh.map_keys! {|k| block }

Replaces the keys in hsh by running them each through block.

If block returns duplicate keys, they will be overwritten in turn.

As of Ruby 2.5 this is equivalent to #transform_keys!

See: #map_keys

hsh.map_pairs {|k, v| block }

Returns a new hash which is a copy of hsh but each key-value pair is replaced by the result of running it through block.

If block returns duplicate keys, they will be overwritten in the resulting hash.

require 'mug/hash/map'

{'a'=>1, 'b'=>2}.map_pairs { |k,v| [k*2, v+1] } #=> {'aa'=>2, 'bb'=>3}
{'a'=>1, 'b'=>2}.map_pairs { ["cat","dog"] }   #=> {'cat'=>'dog'}

hsh.map_pairs! {|k, v| block }

Replaces the keys and values in hsh by running them each through block.

If block returns duplicate keys, they will be overwritten.

See: #map_pairs

hash/merge

Hash

hsh.merge_left other_hash => new_hash

Returns a new hash containing the contents of other_hash and the
contents of hsh. The value for each duplicate key is the value in
hsh when it exists.

hsh.merge_right other_hash => new_hash

Returns a new hash containing the contents of other_hash and the
contents of hsh. The value for each duplicate key is the value in
other_hash when it exists.

hsh.merge_left! other_hash => hsh

Adds the contents of other_hash to hsh. Entries with duplicate
keys are overwritten with the values from other_hash if the
values in hsh are nil.

hsh.merge_right! other_hash => hsh

Adds the contents of other_hash to hsh. Entries with duplicate
keys are overwritten with the values from other_hash unless the
values in other_hash are nil.

hash/operations

Hash

hsh | other_hsh

Returns a new Hash, whose value is the same as this
one, with any extras in other_hash added in.

Useful for default options.

require 'mug/hash/operations'

def foo options={}
  options | {b: 2, c: 2}
end
foo a: 1, b: 1 # => {:a=>1, :b=>1, :c=>2}

hsh + other_hsh

Adds the contents of other_hash to hsh.
Entries with duplicate keys are overwritten with the values from other_hash

require 'mug/hash/operations'

a = {a: 1, b: 1}
b = {b: 2, c: 2}
a + b # => {:a=>1, :b=>2, :c=>2}
b + a # => {:a=>1, :b=>1, :c=>2}

hsh << o

Appends stuff to the hash.

require 'mug/hash/operations'

h = {}
h << {:a=>0}       # h = {:a=>0}
h << {:b=>2,:c=>3} # h = {:a=>0,:b=>2,:c=>3}
h << [:a,1]        # h = {:a=>1,:b=>2,:c=>3}

hash/when

Use a Hash like a case statement.

case key
when /foo/ then "FOO"
when /bar/ then "BAR"
else "DEFAULT"
end

becomes:

h = {
  /foo/ => "FOO",
  /bar/ => "BAR",
}
h.default = "DEFAULT"
h.when key

iff

Object

obj.iff? condition
obj.iff? { condition }

Test for logical equivalence.

Returns true if condition and obj are either
both truthy, or both falsey.

iterator

Iterator

A special class of Enumerator that repeatedly yields values
to a block.

The initial yielded value is given in the constructor, but in
subsequent iterations the result of the previous iteration is
yielded.

new(initial, *args) { |obj, *args| ... }
new(initial, method=:each, *args)

Creates a new Iterator object, which can be used as an
Enumerable.

In the first form, iteration is defined by the given block,
to which the current object and any other args are yielded.

In the second, deprecated, form, a generated Iterator sends the
given method with any +args+ to the iterand.

Use of this form is discouraged. Use Object#iter_for or
Method#to_iter instead.

iterator/for

Object

obj.iter_for(meth, *args)

Creates an Iterator object, which is a subclass of Enumerator that recursively invokes a method on an object.

Initially the receiving object is obj. After each iteration, the receiving object is replaced with the result of the previous iteration.

require 'mug/iterator/for'

0.iter_for(:next).take(5) #=> [1,2,3,4,5]
0.iter_for(:+,2).take(5) #=> [2,4,6,8,10]

iterator/method

Method

meth.to_iter(*args)

Creates an Iterator object, which is a subclass of Enumerator that recursively invokes meth on an object.

Initially the receiving object is the object on which meth is defined. After each iteration, the receiving object is replaced with the result of the previous iteration.

require 'mug/iterator/method'

0.method(:next).to_iter.take(5) #=> [1,2,3,4,5]
0.method(:+).to_iter(2).take(5) #=> [2,4,6,8,10]

loop-with

Kernel

loop_with_index(offset=0) {|i| block }

Repeatedly executes the block, yielding the current iteration
count, which starts from offset. If no block is given, returns
an Enumerator.

loop_with_object(obj) {|o| block }

Repeatedly executes the block, yielding an arbitrary object, obj.

Examples

require 'mug/loop-with'

loop_with_index do |i|
  p i
  break
end

arr = loop_with_object([]) do |a|
  s = gets.chomp
  throw StopIteration if s.empty?
  a << s
end

main

Kernel

__main__
__main__ { block }

Compares the calling source filename with $PROGRAM_NAME ($0).

Returns a falsey value if the calling context is not in the 'main' file.

If called without a block, and the calling context is in the 'main' file,
returns true.

If called with a block, and the calling context is in the 'main' file, the
block is executed and the result is returned.

Examples

require 'mug/main'

if __main__
  puts "the main file"
end

__main__ do
  puts "also the main file"
end

# More advanced example:

if __main__ { ARGV[0] == 'foo' }
  do_foo
end

matchdata/each

MatchData

md.each
md.each { |str| block }

Iterates over each capture group in the MatchData object,
including $& (the entire matched string), yielding the
captured string.

md.each_capture
md.each_capture {|key, str| block }

Iterates over each capture group in the MatchData object,
yielding the capture position and captured string.

The capture positions are either all Strings or all Integers,
depending on whether the original Regexp had named capture
groups or not.

md.each_named_capture
md.each_named_capture {|name, str| block }

Iterates over each named capture group in the MatchData object,
yielding the capture name and string.

md.each_positional_capture(include_names: false)
md.each_positional_capture(include_names: false) {|name, str| block }

Iterates over each positional capture group in the MatchData object,
yielding the capture position and string.

If include_names is given and true, treats named captures
as positional captures.

WARNING: if mixing named and positional captures, no positional
captures will be available using this method!

matchdata/hash

MatchData

md.to_h

Returns a Hash object of capture position => captured string.

The capture positions are either all Strings or all Integers,
depending on whether the original Regexp had named capture
groups or not.

md.named_captures

Returns a Hash object of capture name => captured string.

md.positional_captures(include_names: false)

Returns a Hash object of capture position => captured string.

If include_names is given and true, treats named captures
as positional captures.

WARNING: if mixing named and positional captures, no positional
captures will be available using this method!

maybe

Object

obj.maybe
obj.maybe { block }

Invokes a method on obj iff obj is truthy, otherwise returns obj.

When a block is given, the block is invoked in the scope of obj (i.e. self in the block refers to obj).

When no block is given, maybe returns an object that conditionally delegates methods to obj.

require 'mug/maybe'

# Equivalent to: a && a.b && a.b.c
# except that a and b are only invoked once

# (block form)
a.maybe{ b.maybe{ c } }

# (delegator form)
a.maybe.b.maybe.c

negativity

Numeric

num.negative?

If num is negative (i.e. < 0), returns itself, otherwise returns nil.

num.positive?

If num is positive (i.e. > 0), returns itself, otherwise returns nil.

num.nonnegative?

If num is nonnegative (i.e. >= 0), returns itself, otherwise returns nil.

num.nonpositive?

If num is nonpositive (i.e. <= 0), returns itself, otherwise returns nil.

Examples

require 'mug/negativity'

if i.negative?
  puts "#{i} = 0 - #{-i}"
end

n.positive? or raise('not enough items')

x.nonnegative? || -x

arr.map{|i| i.nonpositive? }.compact

not

Kernel

obj.not
obj.not {|o| block }
obj.not(*a)
obj.not(*a) {|o| block }

Negate a predicate.

Examples

require 'mug/not'

false.not        #=> true
true.not         #=> false

[].not &:empty?  #=> false
[1].not :empty?  #=> true

[1,-2,3].not(:all?) {|e| e > 0 } #=> true

rexproc

Regexp

rex.to_proc

Returns a proc that accepts one argument, that matches against this regexp object.

require 'mug/rexproc'

%w[foo bar baz].select &/\Ab/ #=> ["bar", "baz"]
%w[foo bar baz].reject &/\Ab/ #=> ["foo"]
%w[foo bar baz].find &/\Ab/ #=> "bar"

self

Object

obj.self
obj.self {|o| block }
obj.itself
obj.itself {|o| block }

When a block is given, yields obj to the block and returns the resulting value.

When no block is given, simply returns obj.

Note: this is different from #tap because obj.tap{nil} returns obj, but obj.self{nil} returns nil.

require 'mug/self'

1.self #=> 1
obj.self #=> obj
2.self{|i| i*3 } #=> 6
[1,1,2,2,3].group_by(&:self) #=> {1=>[1,1], 2=>[2,2], 3=>[3]}

1.itself #=> 1
obj.itself #=> obj
2.itself{|i| i*3 } #=> 6
[1,1,2,2,3].group_by(&:itself) #=> {1=>[1,1], 2=>[2,2], 3=>[3]}

obj.revapply(*args) {|*list| block }
obj.cede(*args) {|*list| block }
obj.revapply(*args)
obj.cede(*args)

When a block is given, yields obj and any args to the block and returns the resulting value.

When no block is given, returns an Enumerator.

tau

Defines the true circle constant.

Math::TAU #= 6.283185307179586..

Additionally it expands the BigDecimal/BigMath module:

require 'bigdecimal'
require 'bigdecimal/math'
include BigMath

puts TAU(15)

See http://tauday.com to find out what it's all about.

time

Time

t.to_now

Returns the number of seconds since the time represented by
this Time object.

start = Time.now
#...
duration = start.to_now

t.from_now

Returns the number of seconds until the time represented by
this Time object.

target = Time.new 2117, 1, 1, 0, 0, 0
sleep target.from_now

Time.until t

Returns the number of seconds until t.

Time.since t

Returns the number of seconds since t.

to_h

Removed

Note: for Ruy 2.1, Enumerable#to_h is already defined.

Note: for Ruby <2.0, it is advisable to instead use the to_h gem.

top

Enumerable

enum.top(n=1)
enum.top(n=1) {|a,b| block }

Get the top n items, in order from top to bottom.

Returns an Array even when n is 1.

See: Enumerable#sort

enum.top_by(n=1) {|item| block }

Get the top n items, in order from top to bottom, ordered
by mapping the values through the given block.

Returns an Array even when n is 1. Values that are tied
after mapping are returned in the initial order.

If no block is given, an enumerator is returned instead.

See: Enumerable#sort_by

enum.bottom(n=1)
enum.bottom(n=1) {|a,b| block }

Get the bottom n items, in order from bottom to top.

Returns an Array even when n is 1.

See: Enumerable#sort

enum.bottom_by(n=1) {|item| item }

Get the bottom n items, in order from bottom to top, ordered
by mapping the values through the given block.

Returns an Array even when n is 1. Values that are tied
after mapping are returned in the initial order.

If no block is given, an enumerator is returned instead.

See: Enumerable#sort_by

with

Kernel

with(*args) {|*foo| block }

Yields the arguments to a block.

with(1, 2, 3) {|x, y, z| x + y + z }
#=> 6
Copyright (c) 2013-2020, Matthew Kerwin 

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Contributor Covenant Code of Conduct

Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

Examples of unacceptable behavior include:

Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
mug.gem@kerwin.net.au.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

1. Correction

Community Impact: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

2. Warning

Community Impact: A violation through a single incident or series
of actions.

Consequence: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

3. Temporary Ban

Community Impact: A serious violation of community standards, including
sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

4. Permanent Ban

Community Impact: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within
the community.

Attribution

This Code of Conduct is adapted from the Contributor Covenant,
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct
enforcement ladder
.

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.