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?
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.
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).
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.