EverythingRB

Gem Version Ruby Version Tests

Useful extensions to Ruby core classes that you never knew you needed until now.

Looking for a Software Engineer?

I'm currently looking for opportunities where I can tackle meaningful problems and help build reliable software while mentoring the next generation of developers. If you're looking for a senior engineer with full-stack Rails expertise and a passion for clean, maintainable code, let's talk!

bryan@itsthedevman.com

Table of Contents

Also see: API Documentation

Compatibility

Currently tested on:

  • MRI Ruby 3.2+
  • NixOS (see flake.nix for details)

Installation

Add this line to your application's Gemfile:

gem "everythingrb"

And then execute:

$ bundle install

Or install it yourself as:

$ gem install everythingrb

Core Extensions

Array

join_map

Combines filter_map and join operations in one convenient method. Optionally provides the index to the block.

# Without index
[1, 2, nil, 3].join_map(" ") { |n| n&.to_s if n&.odd? }
# => "1 3"

# With index
["a", "b", "c"].join_map(", ", with_index: true) { |char, i| "#{i}:#{char}" }
# => "0:a, 1:b, 2:c"

# Default behavior without block
[1, 2, nil, 3].join_map(", ")
# => "1, 2, 3"

key_map

Extracts a specific key from each hash in an array.

users = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 }
]

users.key_map(:name)
# => ["Alice", "Bob"]

dig_map

Extracts nested values from each hash in an array using the dig method.

data = [
  { user: { profile: { name: "Alice" } } },
  { user: { profile: { name: "Bob" } } }
]

data.dig_map(:user, :profile, :name)
# => ["Alice", "Bob"]

deep_freeze

Recursively freezes an array and all of its nested elements.

array = ["hello", { name: "Alice" }, [1, 2, 3]]
array.deep_freeze
# => All elements and nested structures are now frozen

Enumerable

join_map

Combines filtering, mapping and joining operations into one convenient method.

# Basic usage with arrays
[1, 2, nil, 3].join_map(", ") { |n| n&.to_s if n&.odd? }
# => "1, 3"

# Works with any Enumerable
(1..10).join_map(" | ") { |n| "num#{n}" if n.even? }
# => "num2 | num4 | num6 | num8 | num10"

# Supports with_index option
%w[a b c].join_map("-", with_index: true) { |char, i| "#{i}:#{char}" }
# => "0:a-1:b-2:c"

Hash

to_struct

Recursively converts a hash into a Struct, including nested hashes and arrays.

hash = { user: { name: "Alice", roles: ["admin", "user"] } }
struct = hash.to_struct
struct.class # => Struct
struct.user.name # => "Alice"
struct.user.roles # => ["admin", "user"]

to_ostruct

Recursively converts a hash into an OpenStruct, including nested hashes and arrays.

hash = { config: { api_key: "secret", endpoints: ["v1", "v2"] } }
config = hash.to_ostruct
config.class # => OpenStruct
config.config.api_key # => "secret"

to_istruct

Recursively converts a hash into an immutable Data structure.

hash = { person: { name: "Bob", age: 30 } }
data = hash.to_istruct
data.class # => Data
data.person.name # => "Bob"

join_map

Similar to Array#join_map but operates on hash values.

{ a: 1, b: 2, c: nil, d: 3 }.join_map(" ") { |k, v| [k, v] if v }
# => "a 1 b 2 d 3"

deep_freeze

Recursively freezes a hash and all of its nested values.

hash = { user: { name: "Alice", roles: ["admin", "user"] } }
hash.deep_freeze
# => Hash and all nested structures are now frozen

Module

attr_predicate

Creates predicate (boolean) methods for instance variables.

class User
  attr_writer :admin
  attr_predicate :admin, :active
end

user = User.new
user.active? # => false
user.admin = true
user.admin? # => true

OpenStruct

each

Alias for each_pair.

struct = OpenStruct.new(a: 1, b: 2)
struct.each { |key, value| puts "#{key}: #{value}" }

map

Maps over OpenStruct entries.

struct = OpenStruct.new(a: 1, b: 2)
struct.map { |key, value| [key, value * 2] }
# => [[:a, 2], [:b, 4]]

filter_map

Combines map and compact operations in one convenient method.

struct = OpenStruct.new(a: 1, b: nil, c: 2)
struct.filter_map { |key, value| value * 2 if value }
# => [2, 4]

join_map

Combines filter_map and join operations in one convenient method.

config = OpenStruct.new(
  alice: {roles: ["admin"]},
  bob: {roles: ["user"]},
  carol: {roles: ["admin"]}
)

config.join_map(", ") { |key, value| key if value[:roles].include?("admin") }
# => "alice, carol"

String

to_h / to_a

Parses JSON string into a Ruby Hash or Array.

'{"name": "Alice"}'.to_h
# => {name: "Alice"}

'["Alice"]'.to_h # Or you can use #to_a for different readability
# => ["Alice"]

to_istruct

Parses JSON string into an immutable Data structure.

'{"user": {"name": "Alice"}}'.to_istruct
# => #<data user=#<data name="Alice">>

to_ostruct

Parses JSON string into an OpenStruct.

'{"user": {"name": "Alice"}}'.to_ostruct
# => #<OpenStruct user=#<OpenStruct name="Alice">>

to_struct

Parses JSON string into a Struct.

'{"user": {"name": "Alice"}}'.to_struct
# => #<struct user=#<struct name="Alice">>

to_deep_h

Recursively parses nested JSON strings within a structure.

nested_json = {
  users: [
    {name: "Alice", roles: ["admin", "user"]}.to_json,
  ]
}.to_json

nested_json.to_deep_h
# => {users: [{name: "Alice", roles: ["admin", "user"]}]}

with_quotes / in_quotes

Wraps the string in double quotes

"Hello World".with_quotes
# => "\"Hello World\""

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b feature/my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin feature/my-new-feature)
  5. Create new Pull Request

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

License

The gem is available as open source under the terms of the MIT License.

Changelog

See CHANGELOG.md for a list of changes.

Credits

  • Author: Bryan "itsthedevman"