[ruby-core:77335] [Ruby trunk Bug#12521] Syntax for retrieving argument without removing it from double-splat catch-all

From: eregontp@...
Date: 2016-09-21 11:24:14 UTC
List: ruby-core #77335
Issue #12521 has been updated by Benoit Daloze.


Guyren Howe wrote:

> ```ruby
> def render name::, something::, foo::, **context
>   … now use foo …
> end
> ```

So this would be syntactic sugar for essentially this?

```ruby
def render **context
  name = context.fetch :name
  something = context.fetch :something
  foo = context.fetch :foo
  … now use foo …
end
```

It's true that's it's verbose.
I'm not particularly fond of double or triple operators with slightly different semantics though.

From a design point of view, it seems a parameter object would work well here,
and would potentially avoid conflicts for two :name with different meaning.

----------------------------------------
Bug #12521: Syntax for retrieving argument without removing it from double-splat catch-all
https://bugs.ruby-lang.org/issues/12521#change-60581

* Author: Guyren Howe
* Status: Closed
* Priority: Normal
* Assignee: 
* ruby -v: 
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
There is an interesting style of programming that is *almost* really easy to do in Ruby. It would work elegantly with a simple change. A double-colon keyword argument should be available that will still leave the same argument captured by a double-splat argument if present. With this available, it becomes easy to pass down a "context" through a call chain.

Consider this:

```ruby
def controller name::, **context
  …
  log_then_render something:, name:, **context
end

def log_then_render **context
  log context
  complex_logic_then_render **context
end

def complex_logic_then_render name::, **context
…
Bunch of further calls

def render name::, something::, **context
  …
end
```

Now assume I decide render needs a foo argument, that I obtain in my controller. The only functions that are aware of or have any need for the argument are controller and render. With functions written in this style, I only need to modify the two functions that need to know about the argument:

```ruby
def controller name::, **context
  …
  log_then_render something:, name:, foo: foo_value, **context
end

… no changes …

def render name::, something::, foo:: **context
  … now use foo …
end
```

This is, I accept, unusual. I've not seen a language that offers this sort of feature (I call them, for various reason I don't have time to go into now, FREST functions). I can basically implement this now with a decorator, but it's a little ugly and slow.

It just occurred to me that an alternative would be a triple-splat final argument (or some such) that gathers all the keywords.

There is a related problem with the way double-splat and regular keyword arguments interact that should be fixed anyway.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next