Project

handy_hash

0.0
No commit activity in last 3 years
No release in over 3 years
HandyHash is a Hash object that supply handy ways for accessing data and merging.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 2.0
~> 10.0
~> 3.0

Runtime

 Project Readme

HandyHash

HandyHash - это небольшая обертка для Hash, которая может быть весьма удобна в некоторых случаях.

Возможности:

  • доступ к данным через методы-геттеры (см. Использование)
  • рекурсивный freeze
  • рекурсивное слияние + специальный DSL для описания слияния (см. Использование)

Установка

Добавить в Gemfile слудющую строку:

gem 'handy_hash'

Запустить:

$ bundle

Или установить гем вручную:

$ gem install handy_hash

Использование

Инициализация:

  data = HandyHash.new(
    host_name: 'www.myapp.com',
    some_lib: {
      path: '/lib/some_lib',
      init_opts: {
        flags: 3465873,
        secret: "78396nxry837d"
      },
      methods: %w(one two)
    }
  )

Получать значения можно разными способами.

Как из обычного хэша (работает как HashWithIndifferentAccess):

  data[:host_name]                      # => "www.myapp.com"
  data["some_lib"][:init_opts]          # => {"flags" => 3465873, "secret" => "78396nxry837d"}
  data["some_lib"]["init_opts"][:flags] # => 3465873

В этом случае никакой проверки на присутствие элемента не производится:

  data[:foo]        # => nil
  data[:foo][:bar]  # => NoMethodError: undefined method `[]' for nil:NilClass

Можно получать значения, используя геттеры:

  data.host_name                  # => "www.myapp.com"
  data.some_lib.init_opts         # => {"flags" => 3465873, "secret" => "78396nxry837d"}
  data.some_lib.init_opts[:flags] # => 3465873
  data.some_lib.init_opts.secret  # => "78396nxry837d"

В этом случае можно "безопасно" спускаться на любую глубину, не опасаясь возникновения исключения:

  data.foo.present?         # => false
  data.foo.bar.baz.present? # => false
  data.foo.bar[:baz]        # => nil

Есть возможность принудительно вызвать исключение приотсутствии определенного элемента:

  data.some_lib.path! # => "/lib/some_lib"
  data.foo!.bar       # => HandyHash::ValueMissingError: value missing: "foo"

В качестве аргумента можно передать значение по умолчанию:

  data.some_lib.init_opts.flags(0) # => 3465873
  data.foo.bar.baz(666)            # => 666

Если ключ хэша соответствует названию какого-то существующего метода объекта HandyHash (например, methods, hash, patch и т.д.), то необходимо оборачивать метод знаком _:

  data.some_lib._methods_ # => ["one", "two"]

Слияние (переопределение значений)

Слияние производится с помощью метода #patch, который возвращает новый объект HandyHash с новыми значениями. Значения в исходном объекте не меняются.

Слияние производится рекурсивно во всех нижележащих Hash-объектах.

Выполнить слияние можно, передав методу #patch объект Hash:

  new_data = data.patch(
    some_lib: {
      path: '/lib/other_path'
    },
    foo: :bar
  )
  new_data.some_lib.path # => '/lib/other_path'
  new_data.foo           # => :bar

Можно с помощью DSL:

  new_data = data.patch{
    some_lib {
      path '/lib/other_path'
    }
    foo :bar
  }
  new_data.some_lib.path # => '/lib/other_path'
  new_data.foo           # => :bar

Для экономии строк при изменениях значений на глубоких уровнях иерархии можно использовать цепочки методов:

  new_data = data.patch{
    some_lib.init_opts.secret 'abc'
    foo.bar.baz 123
  }
  new_data.some_lib.init_opts.secret # => "abc"
  new_data.foo.bar.baz               # => 123

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/stp-che/handy_hash.

License

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