Coder Social home page Coder Social logo

westonganger / rearmed-rb Goto Github PK

View Code? Open in Web Editor NEW
41.0 6.0 1.0 114 KB

A collection of helpful methods and monkey patches for Arrays, Hash, Enumerables, Strings, Objects & Dates in Ruby

License: MIT License

Ruby 100.00%
monkey-patching rails ruby utility

rearmed-rb's Introduction

Rearmed Ruby

Gem Version CI Status RubyGems Downloads Buy Me a Coffee

A collection of helpful methods and monkey patches for Arrays, Hash, Enumerables, Strings, Objects & Dates in Ruby. Rearmed is a collection of plugins which are driven by making life easier & coding more natural.

The difference between this library and others is that all monkey patching is performed in an opt-in way because you shouldnt be using methods you dont know about anyways.

When possible I have placed the method implementations inside the Rearmed module so if you don't like monkey patching or are working on the project with a team then you can use these methods instead. You can then skip the config and see how to use each implementation below the relevant methods documentation.

Install

Add the following line to your gemfile:

gem 'rearmed'

Usage

Setup Monkey Patches (all are opt-in)

# config/initializers/rearmed.rb

Rearmed.enabled_patches = {
  array: {
    delete_first: false,
    dig: false,
    not_empty: false
  },
  date: {
    now: false
  },
  enumerable: {
    natural_sort: false,
    natural_sort_by: false,
    select_map: false
  },
  hash: {
    compact: false,
    deep_set: false,
    dig: false,
    join: false,
    only: false,
    to_struct: false
  },
  integer: {
    length: false
  },
  object: {
    bool?: false,
    false?: false,
    in: false,
    not_nil: false,
    true?: false
  },
  string: {
    begins_with: false,
    casecmp?: false,
    ends_with: false,
    match?: false,
    starts_with: false,
    to_bool: false,
    valid_float: false,
    valid_integer: false
  }
}

Rearmed.apply_patches!

Some other argument formats the enabled_patches option accepts are:

### Enable everything
Rearmed.enabled_patches = :all

### Disable everything
Rearmed.enabled_patches = nil

### Hash values can be boolean/nil values also
Rearmed.enabled_patches = {
  array: true, 
  date: {
    now: true
  },
  enumerable: true, 
  hash: false, 
  integer: false, 
  object: nil, 
  string: nil
}

By design, once Rearmed.apply_patches! is called then Rearmed.enabled_patches is no longer editable and Rearmed.apply_patches! cannot be called again. If you try to do so, it will raise a PatchesAlreadyAppliedError. There is no-built in way of changing the patches, if you need to do so (which you shouldn't) that is up to you to figure out.

Array Methods

array = [1,2,1,4,1]
array.delete_first(1) # => 1
puts array #=> [2,1,4,1]
array.delete_first{|x| 1 == x} # => 1
puts array # => [2,4,1]
array.delete_first # => 2
puts array # => [4,1]

array.not_empty? # => true

# Only monkey patched if using Ruby 2.2.x or below as this method was added to Ruby core in 2.3.0
items = [{foo: ['foo','bar']}, {test: 'thing'}]
items.dig(0, :foo, 1) # => 'bar'
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)

Enumerable Methods (Array, Hash, etc.)

items = ['1.1', '1.11', '1.2']
items.natural_sort 
items.natural_sort(reverse: true) # because natural_sort does not accept a block, accepting PR's on this
# or without monkey patch: Rearmed.natural_sort(items) or Rearmed.natural_sort(items, reverse: true)

items = [{version: "1.1"}, {version: "1.11"}, {version: "1.2"}]
items.natural_sort_by{|x| x[:version]} 
# or without monkey patch: Rearmed.natural_sort_by(items){|x| x[:version]}

items = [{version: "1.1"}, {version: nil}, {version: false}]
items.select_map{|x| x[:version]} #=> [{version: "1.1"}]
# or without monkey patch: Rearmed.select_map(items){|x| x[:version]}

Date

Date.now

Hash Methods

hash.join{|k,v| "#{k}: #{v}\n"}

hash = {foo: 'foo', bar: 'bar', other: 'other'}
hash.only(:foo, :bar) # => {foo: 'foo'}
# or without monkey patch: Rearmed.hash_only(hash, :foo, :bar)

hash.only!(:foo, :bar)

hash.to_struct
# or without monkey patch: Rearmed.hash_to_struct(hash)

# Only monkey patched if using Ruby 2.2.x or below as this method was added to Ruby core in 2.3.0
items = [{foo: ['foo','bar']}, {test: 'thing'}]
items.dig(0, :foo, 1) # => 'bar'
# or without monkey patch: Rearmed.dig(items, 0, :foo, 1)

# Only monkey patched if using Ruby 2.3.x or below as this method was added to Ruby core in 2.4.0
hash.compact
# or without monkey patch: Rearmed.hash_compact(hash)
hash.compact!

hash.deep_set([:foo, :bar, :name], "John") # => {foo: {bar: {name: "John"}}}
# or without monkey patch: Rearmed.hash_deep_set(hash, keys_array, value)

Object

my_var.not_nil?

# Only monkey patched if not using ActiveSupport / Rails as this method is already defined there
my_var.in?([1,2,3])
my_var.in?(1,2,3) # or with splat arguments

my_var.bool? # if is true or false boolean value
my_var.true? # if is true boolean value
my_var.false? # if is false boolean value

String

'123'.valid_integer?
# or without monkey patch: Rearmed.valid_integer?('123')

'123.123'.valid_float? 
# or without monkey patch: Rearmed.valid_float?('123.123')

'123.123'.valid_number? 
# or without monkey patch: Rearmed.valid_number?('123.123')

'true'.to_bool 
# or without monkey patch: Rearmed.to_bool('true')

'foo'.match?(/fo/) #=> true, this method returns a convenient boolean value instead of matchdata

# alias of start_with? and end_with? to have more sensible method names
'foo'.starts_with?('fo') # => true
'foo'.begins_with?('fo') # => true
'bar'.ends_with?('ar') # => true

# Only monkey patched if using Ruby 2.3.x or below as this method was added to Ruby core in 2.4.0
'foo'.casecmp?('FOO') #=> true
'foo'.casecmp?('FOOBAR') #=> false
# or without monkey patch: Rearmed.casecmp?('foo', 'FOO')

Contributing / Todo

If your looking to contribute here is a list of outstanding items:

  • Get the natural_sort method to accept a block

To request or add a method, please raise an issue and we can discuss the implementation.

Credits

Created by Weston Ganger - @westonganger

Other Libraries in the Rearmed family of Plugins

rearmed-rb's People

Contributors

timboisvert avatar westonganger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

timboisvert

rearmed-rb's Issues

Wrong Regex Anchor Being Used Most Everywhere

irb [2.5.0] (rearmed-rb)$ Rearmed::String.valid_integer?("ABC\n123")
=> true
irb [2.5.0] (rearmed-rb)$ Rearmed::String.valid_integer?("")
=> true

Need to use \A and \z instead of ^ and $ and drop \d* for \d+.

Add CIHash

################################################## CIHash (Case-Insensitive Hash) - HELPFUL FOR HASH KEY COMPARISONS WHERE WE NEED TO IGNORE CASE ERRORS
class CIHash < HashWithIndifferentAccess
  def [](k)
    if self.has_key?(k)
      return super(k)
    else
      alt_key = self.keys.detect{|x| x.to_s.casecmp?(k) }

      if alt_key
        return super(alt_key)
      else
        return nil;
      end
    end
  end
end

Add CIString

################################################## CIString (Case-Insensitive String) - HELPFUL FOR STRING COMPARISONS WHERE WE NEED TO IGNORE CASE ERRORS
class CIString < String
  def initialize(*args)
    if args[0].nil?
      args[0] = ""
    end

    super
  end

  def ==(val)
    val.is_a?(String) ? self.casecmp?(val) : false
  end

  def ===(val)
    val.is_a?(String) ? self.casecmp?(val) : false
  end
end

String.class_eval do
  prepend(CIStringFix = Module.new do
    def ==(val)
      val.is_a?(CIString) ? self.casecmp?(val) : super
    end

    def ===(val)
      val.is_a?(CIString) ? self.casecmp?(val) : super
    end
  end)
end

Add SafeHash

################################################## SafeHash - ALL VALUE FETCHING OCCURS USING FETCH METHOD WHICH RAISES ERROR IF KEY NOT FOUND
class SafeHash < HashWithIndifferentAccess
  def [](k)
    self.fetch(k)
  end
end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.