From: bradley.t.herman@... Date: 2018-10-15T17:36:21+00:00 Subject: [ruby-core:89408] [Ruby trunk Feature#15049] [Request] Easily access all keyword arguments within a method Issue #15049 has been updated by bherms (Bradley Herman). duerst (Martin D��rst) wrote: > Maybe I'm totally confused, but what's wrong with using **keyword_arguments? I agree with zverok's answer. The main reason for not just doing **args is that you lose several of the benefits of using keyword arguments in the first place: 1) lowering connascence , 2) enforcing requirements (required kargs), 3) settings defaults. ~~~ ruby def post(required:, other_required:, defaulted: 'default') end def post(**kargs) raise ArgumentError, 'missing keyword "required"' unless kargs.has_key?(:required) raise ArgumentError, 'missing keyword "other_required"' unless kargs.has_key?(:other_required) kargs.reverse_merge!(defaulted: 'default') end ~~~ Those two method definitions are *very* different IMO and the first is far superior. Obviously we could DRY up the required argument checks, but it still wouldn't be ideal. ---------------------------------------- Feature #15049: [Request] Easily access all keyword arguments within a method https://bugs.ruby-lang.org/issues/15049#change-74448 * Author: bherms (Bradley Herman) * Status: Feedback * Priority: Normal * Assignee: * Target version: ---------------------------------------- As a developer, I'd like to leverage the power of keyword arguments (requirements, defaults, etc) and then be able to access a hash of all the arguments supplied. ~~~ ruby def foo(bar:, baz: 1, qux: 2...) post('/', body: kargs) end ~~~ This is currently possible by leveraging the RubyVM debug inspector and some meta programming to retrieve the binding and name of the calling method. There is a gem https://github.com/banister/binding_of_caller that abstracts away the logic of crawling through the frame bindings in the debug inspector to find the binding of the caller, but I feel like this functionality would be useful in Ruby. With the binding_of_caller gem, you can hack together a kargs method like so: ~~~ ruby def kargs method(caller_locations(1,1)[0].label).parameters.map do |(_type, name)| [name, binding.of_caller(2).local_variable_get(name)] end.to_h end ~~~ This gets the name of the calling method, pulls the local variables from the method, retrieves the binding, and then retrieves the variables from the binding. By exposing a simpler API to retrieve the caller binding, a `kargs` method could be added to Ruby fairly easily I would think. -- https://bugs.ruby-lang.org/ Unsubscribe: