How to Implement Options Hashes in Ruby

Ruby Array#select with an options hash to match on

You may be trying to over complicate this. How about this

my_array = [
{foo: 'a', bar: 'b', baz: 'c'},
{foo: 1, bar: 2, baz: 3},
{foo: 'A', bar: 'B', baz: 'C'},
{foo: 11, bar: 12, baz: 13}
]
finder = {foo: 'a', bar: 'b'}
my_array.select {|h| h.values_at(*finder.keys) == finder.values }
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]

Hash#values_at uses the given keys to return the appropriate values which in your case should match the values for those keys in the "finder" Hash.

To make it work explicitly the way you explained we can define a singleton method for my_array as such:

my_array.define_singleton_method(:search_by) do |opts|
self.select {|h| h.values_at(*opts.keys) == opts.values}
end

my_array.search_by(foo: 'a', bar: 'b')
#=> [{:foo=>"a", :bar=>"b", :baz=>"c"}]
my_array.search_by(foobar: 'n')
#=> []
my_array << {foo: 11,bar: 15,baz: 'c'}
my_array.search_by(foo: 11)
#=>[{:foo=>11, :bar=>12, :baz=>13}, {:foo=>11, :bar=>15, :baz=>"c"}]

Create a ruby method that accepts a hash of parameters and adds them to my method's hash

If you want to be able to override your options, you can do it using Hash#reverse_merge method:

def n(options = {})
opts = options.reverse_merge(a: 1, b: 2)
# ...
end

Quickly setting instance variables with options hash in Ruby?

def initialize(opts={})
opts.each { |k,v| instance_variable_set("@#{k}", v) }
end

What's a nice clean way to use an options hash with defaults values as a parameter in ruby

If you're using Rails (not just plain Ruby), a slightly shorter method is

def foo(options = {})
options.reverse_merge! { ... defaults ... }
end

This has the added advantage of allowing you to do multiple lines a tad bit more cleanly:

def foo(options = {})
options.reverse_merge!(
:some_default => true,
:other_default => 5
)
end

How do methods use hash arguments in Ruby?

Example:

def foo(regular, hash={})
puts "regular: #{regular}"
puts "hash: #{hash}"
puts "a: #{hash[:a]}"
puts "b: #{hash[:b]}"
end

foo("regular argument", a: 12, :b => 13)

I use hash={} to specify that the last argument is a hash, with default value of empty hash. Now, when I write:

foo("regular argument", a: 12, :b => 13)

It's actually a syntactic sugar for:

foo("regular argument", {a: 12, :b => 13})

Also, {a: 12} is syntactic sugar for {:a => 12}.

When all of this is combined together, you get a syntax that looks similar to named arguments in other languages.

How do I pass a hash of options to a rails method?

Simply passing the hash will work. Like this:

m = {data:{toggle:true}, class:"btn btn-success"}    

link_to 'Click Me', '/alu', m
#=> <a data-toggle="true" class="btn btn-success" href="/alu">Click Me</a>

When to use keyword arguments and options hashes?

There is a rule in The Ruby Style Guide for it:

Use keyword arguments instead of option hashes.

# bad
def some_method(options = {})
bar = options.fetch(:bar, false)
puts bar
end

# good
def some_method(bar: false)
puts bar
end

It is a de facto coding standard and if you follow it you will never have a problem with your customers' reviewing of your code.

There is only one exception to this rule: if your method needs a really large number of different rarely used options that are really hard to list in the arguments list, only then it is worth using the option hash. But such situations should be avoided if possible.



Related Topics



Leave a reply



Submit