Reputation:
I have this method
def method1
{
headers: { 'Content-Type' => 'application/json' }
}
end
and this another method for merge a another key and value into this method1 hash, so
def merge_hash
method1.merge!(body: { params: 123 }
end
so when i call method1 again i expect he returns a marged body and my questions is why not this happens or how i can do it?
Upvotes: 0
Views: 178
Reputation: 22366
Perhaps this comes close to what you look at:
class MyClass
attr_reader :method1
def initialize
@method1 = { headers: { 'Content-Type' => 'application/json' } }
end
def merge_hash
@method1.merge!(body: { params: 123 }
end
end
Hence, if you have a
o = MyClass.new
the first o.method1
will return the initial hash, but after a
o.merge_hash
an o.method1
will return the modified hash.
Upvotes: 0
Reputation: 8898
Of course method1
's return value does not change, because you haven't changed the method itself.
You can use the old and evil technique called alias method chain.
# Define a new method `method1_without_body`
# whose implementation is exactly the same
# as `method1` at this moment.
alias method1_without_body method1
# Define a new method that calls `method1_without_body`.
# Make sure that it does NOT call `method1`,
# or you'll get a stack overflow.
def method1_with_body
method1_without_body.merge!(body: { params: 123 })
end
# Define a new method `method1`
# whose implementation is exactly the same
# as `method1_with_body`.
# This method shadows the previous implementation of `method1`.
alias method1 method1_with_body
or if you are using Rails < 5, then just
def method1_with_body
method1_without_body.merge!(body: { params: 123 })
end
alias_method_chain :method1, :body
then when you call method1
, it returns the hash with both headers and body.
By the way, this technique was deprecated since Rails 5 and was totally removed later (I forgot in which minor version).
Upvotes: 0
Reputation: 3201
Each time you call method1
it returns a new object:
> method1.object_id
=> 47220476550040
> method1.object_id
=> 47220476543700
To achieve what you want you can memorize it after the first call:
def method1
@method1 ||= {
headers: { 'Content-Type' => 'application/json' }
}
end
> method1.object_id
=> 47220477154400
> method1.object_id
=> 47220477154400
I suggest to not mutate a hash this way because it can lead to bugs.
Upvotes: 3