ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-dev:50610] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash
       [not found] <redmine.issue-14973.20180807151247@ruby-lang.org>
@ 2018-08-07 15:12 ` manga.osyo
  2018-08-07 16:07 ` [ruby-dev:50611] " shevegen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 4+ messages in thread
From: manga.osyo @ 2018-08-07 15:12 UTC (permalink / raw)
  To: ruby-dev

Issue #14973 has been reported by osyo (manga osyo).

----------------------------------------
Feature #14973: Proposal of percent literal to expand Hash
https://bugs.ruby-lang.org/issues/14973

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## 概要

変数名から `{ 変数名: 変数の値 }` という Hash を定義するための %記法の提案です。
以前からちょくちょく[提案されていた](https://bugs.ruby-lang.org/issues/14579)

```ruby
x = 1
y = 2
h = {x:, y:}
p h #=> {:x=>1, :y=>2}
```

のような ES6 ライクな構文を `{}` 構文ではなくて %記法で定義するものになります。


## 仕様

```ruby
hoge = 1
foo = 2
bar = 3

# スペース区切りの変数名をキー、変数の値を Hash の値として展開する
%h(hoge foo bar) # => { hoge: 1, foo: 2, bar: 3 }
```

これは以下と同等の処理になります。

```ruby
hoge = 1
foo = 2
bar = 3

{ hoge: eval("hoge"), foo: eval("foo"), bar: eval("bar") } # => { hoge: 1, foo: 2, bar: 3 }
```

### ローカル変数以外

内部で `eval` を使用しているので、そのコンテキストで評価できればローカル変数以外も使用することが出来ます。

```ruby
def meth
	"meth"
end

@hoge = 42
Foo = "str"

p %h(meth @hoge Foo $stdout)
# => {:meth=>"meth", :@hoge=>42, :Foo=>"str", :$stdout=>#<IO:<STDOUT>>}
```

キーは変数名そのままです(`$` や `@` がついたまま。


### 重複したキーがある場合

キーが重複している場合、`{}` と同様に2回目以降は無視されます。

```ruby
hoge = 42
foo = "str"

%h(hoge foo hoge)
# => {:hoge=>42, :foo=>"str"}
```


### キーの変数が存在しない場合

```ruby
hoge = 42
foo = "str"

%h(hoge foo bar)
# Error: undefined local variable or method `bar' for main:Object (NameError)
```


### Hash 内で展開

Hash なので `**` で展開できます。

```ruby
hoge = 42
foo = "str"

{ bar: "bar", **%h(hoge foo) }
# => {:bar=>"bar", :hoge=>42, :foo=>"str"}
```

## 式展開

`%I` などと同様に式展開を行います。

```ruby
hoge = 42
foo = "hoge"

%h(#{foo})
# => {:hoge=>42}
```


## ユースケース

### キーワード引数に渡す

```ruby
Model = Struct.new(:tag, :name, :age, keyword_init: true)

def create_human(name:, age:)
	# ** で Hash を展開して渡す
	Model.new(tag: :human, **%h(name age))
	# Model.new(tag: :human, name: name, age: age)
end

name = "mami"
age = 15
# 変数をまとめて渡す
create_human(%h(name age)) # => #<struct Model tag=:human, name="mami", age=15>
# create_human(name: name, age: age)
```

### デバッグ出力として利用する

```ruby
class Hash
	# 適当なデバッグ出力用メソッド
	def debug_output
		each { |key, value|
			puts "#{key}: #{value}"
		}
	end
end

def create(name, age)
	# 引数を確認するためのデバッグ出力
	%h(name age).debug_output
end

name = "homu"
age = 14
create(name, age)
# output:
# name: homu
# age: 14
```

## その他

* キーは Symbol で定義 → String 版もあったほうがよいだろうか
* 式展開のみ実装 → `%i` みたいな式展開を行わないでほしいユースケースが思いつかなかった
* なぜ `%h` という名前? → `Hash` だから…


以上、任意の変数名から Hash を展開する `%h` 記法の提案でした。
ご意見等あればコメント頂けると助かります。


## 関連するチケット

https://bugs.ruby-lang.org/issues/11105
https://bugs.ruby-lang.org/issues/14579
https://bugs.ruby-lang.org/issues/13137


---Files--------------------------------
hash_expand.patch (7.3 KB)


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-dev:50611] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash
       [not found] <redmine.issue-14973.20180807151247@ruby-lang.org>
  2018-08-07 15:12 ` [ruby-dev:50610] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash manga.osyo
@ 2018-08-07 16:07 ` shevegen
  2018-08-09  6:55 ` [ruby-dev:50616] " knu
  2019-01-30 19:13 ` [ruby-dev:50777] " blake.h.l.west
  3 siblings, 0 replies; 4+ messages in thread
From: shevegen @ 2018-08-07 16:07 UTC (permalink / raw)
  To: ruby-dev

Issue #14973 has been updated by shevegen (Robert A. Heiler).


I can not read japanese but I believe I can understand part of this 
proposal (the ruby code examples).

If I understood the examples correctly then one part of the proposal
is to add support for:

    %h( ) 

(Possibly meaning to use a hash, and expanding the variables used
within itself, like in the example:)

    %h( hoge foo bar )

If this is the case then I think this is a very interesting suggestion.
(I can't say much about the other examples given, so my comment
refers primarily to %h() alone and local variables. I have no particularly
strong opinion about using instance variables, constants or global
variables there - I think local variables alone are a quite interesting
example; it seems to fit to other shortcuts, such as %w() for constructing
Arrays ).

In one of the older linked in issues e. g. the one by Shugo Maeda, nobu
wrote that there were conflicts with the syntax used in the suggestion. I
do not know if this is the case here (if I understood it correctly,
the example here is not the same, e. g. uses another syntax).

It may be useful to see if there are any problems with the syntax
here; and if not whether this may have a chance to be implemented.

Since this keeps coming up in one way or another, even with different
syntax, it may be useful to discuss this eventually at a developer
meeting.

Personally I like the idea behind the suggestion here made by @osyo.

----------------------------------------
Feature #14973: Proposal of percent literal to expand Hash
https://bugs.ruby-lang.org/issues/14973#change-73355

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## 概要

変数名から `{ 変数名: 変数の値 }` という Hash を定義するための %記法の提案です。
以前からちょくちょく[提案されていた](https://bugs.ruby-lang.org/issues/14579)

```ruby
x = 1
y = 2
h = {x:, y:}
p h #=> {:x=>1, :y=>2}
```

のような ES6 ライクな構文を `{}` 構文ではなくて %記法で定義するものになります。


## 仕様

```ruby
hoge = 1
foo = 2
bar = 3

# スペース区切りの変数名をキー、変数の値を Hash の値として展開する
%h(hoge foo bar) # => { hoge: 1, foo: 2, bar: 3 }
```

これは以下と同等の処理になります。

```ruby
hoge = 1
foo = 2
bar = 3

{ hoge: eval("hoge"), foo: eval("foo"), bar: eval("bar") } # => { hoge: 1, foo: 2, bar: 3 }
```

### ローカル変数以外

内部で `eval` を使用しているので、そのコンテキストで評価できればローカル変数以外も使用することが出来ます。

```ruby
def meth
	"meth"
end

@hoge = 42
Foo = "str"

p %h(meth @hoge Foo $stdout)
# => {:meth=>"meth", :@hoge=>42, :Foo=>"str", :$stdout=>#<IO:<STDOUT>>}
```

キーは変数名そのままです(`$` や `@` がついたまま。


### 重複したキーがある場合

キーが重複している場合、`{}` と同様に2回目以降は無視されます。

```ruby
hoge = 42
foo = "str"

%h(hoge foo hoge)
# => {:hoge=>42, :foo=>"str"}
```


### キーの変数が存在しない場合

```ruby
hoge = 42
foo = "str"

%h(hoge foo bar)
# Error: undefined local variable or method `bar' for main:Object (NameError)
```


### Hash 内で展開

Hash なので `**` で展開できます。

```ruby
hoge = 42
foo = "str"

{ bar: "bar", **%h(hoge foo) }
# => {:bar=>"bar", :hoge=>42, :foo=>"str"}
```

## 式展開

`%I` などと同様に式展開を行います。

```ruby
hoge = 42
foo = "hoge"

%h(#{foo})
# => {:hoge=>42}
```


## ユースケース

### キーワード引数に渡す

```ruby
Model = Struct.new(:tag, :name, :age, keyword_init: true)

def create_human(name:, age:)
	# ** で Hash を展開して渡す
	Model.new(tag: :human, **%h(name age))
	# Model.new(tag: :human, name: name, age: age)
end

name = "mami"
age = 15
# 変数をまとめて渡す
create_human(%h(name age)) # => #<struct Model tag=:human, name="mami", age=15>
# create_human(name: name, age: age)
```

### デバッグ出力として利用する

```ruby
class Hash
	# 適当なデバッグ出力用メソッド
	def debug_output
		each { |key, value|
			puts "#{key}: #{value}"
		}
	end
end

def create(name, age)
	# 引数を確認するためのデバッグ出力
	%h(name age).debug_output
end

name = "homu"
age = 14
create(name, age)
# output:
# name: homu
# age: 14
```

## その他

* キーは Symbol で定義 → String 版もあったほうがよいだろうか
* 式展開のみ実装 → `%i` みたいな式展開を行わないでほしいユースケースが思いつかなかった
* なぜ `%h` という名前? → `Hash` だから…


以上、任意の変数名から Hash を展開する `%h` 記法の提案でした。
ご意見等あればコメント頂けると助かります。


## 関連するチケット

https://bugs.ruby-lang.org/issues/11105
https://bugs.ruby-lang.org/issues/14579
https://bugs.ruby-lang.org/issues/13137


---Files--------------------------------
hash_expand.patch (7.3 KB)


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-dev:50616] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash
       [not found] <redmine.issue-14973.20180807151247@ruby-lang.org>
  2018-08-07 15:12 ` [ruby-dev:50610] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash manga.osyo
  2018-08-07 16:07 ` [ruby-dev:50611] " shevegen
@ 2018-08-09  6:55 ` knu
  2019-01-30 19:13 ` [ruby-dev:50777] " blake.h.l.west
  3 siblings, 0 replies; 4+ messages in thread
From: knu @ 2018-08-09  6:55 UTC (permalink / raw)
  To: ruby-dev

Issue #14973 has been updated by knu (Akinori MUSHA).


For debugging purposes, you could have a method like this:

```ruby
class Binding
  def dump(*syms)
    pp syms.lazy.map { |sym| [sym, local_variable_get(sym)] }.to_h
  end
end

a = 1
b = 2
binding.dump(:a, :b) # prints "{:a=>1, :b=>2}"
```

----------------------------------------
Feature #14973: Proposal of percent literal to expand Hash
https://bugs.ruby-lang.org/issues/14973#change-73409

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## 概要

変数名から `{ 変数名: 変数の値 }` という Hash を定義するための %記法の提案です。
以前からちょくちょく[提案されていた](https://bugs.ruby-lang.org/issues/14579)

```ruby
x = 1
y = 2
h = {x:, y:}
p h #=> {:x=>1, :y=>2}
```

のような ES6 ライクな構文を `{}` 構文ではなくて %記法で定義するものになります。


## 仕様

```ruby
hoge = 1
foo = 2
bar = 3

# スペース区切りの変数名をキー、変数の値を Hash の値として展開する
%h(hoge foo bar) # => { hoge: 1, foo: 2, bar: 3 }
```

これは以下と同等の処理になります。

```ruby
hoge = 1
foo = 2
bar = 3

{ hoge: eval("hoge"), foo: eval("foo"), bar: eval("bar") } # => { hoge: 1, foo: 2, bar: 3 }
```

### ローカル変数以外

内部で `eval` を使用しているので、そのコンテキストで評価できればローカル変数以外も使用することが出来ます。

```ruby
def meth
	"meth"
end

@hoge = 42
Foo = "str"

p %h(meth @hoge Foo $stdout)
# => {:meth=>"meth", :@hoge=>42, :Foo=>"str", :$stdout=>#<IO:<STDOUT>>}
```

キーは変数名そのままです(`$` や `@` がついたまま。


### 重複したキーがある場合

キーが重複している場合、`{}` と同様に2回目以降は無視されます。

```ruby
hoge = 42
foo = "str"

%h(hoge foo hoge)
# => {:hoge=>42, :foo=>"str"}
```


### キーの変数が存在しない場合

```ruby
hoge = 42
foo = "str"

%h(hoge foo bar)
# Error: undefined local variable or method `bar' for main:Object (NameError)
```


### Hash 内で展開

Hash なので `**` で展開できます。

```ruby
hoge = 42
foo = "str"

{ bar: "bar", **%h(hoge foo) }
# => {:bar=>"bar", :hoge=>42, :foo=>"str"}
```

## 式展開

`%I` などと同様に式展開を行います。

```ruby
hoge = 42
foo = "hoge"

%h(#{foo})
# => {:hoge=>42}
```


## ユースケース

### キーワード引数に渡す

```ruby
Model = Struct.new(:tag, :name, :age, keyword_init: true)

def create_human(name:, age:)
	# ** で Hash を展開して渡す
	Model.new(tag: :human, **%h(name age))
	# Model.new(tag: :human, name: name, age: age)
end

name = "mami"
age = 15
# 変数をまとめて渡す
create_human(%h(name age)) # => #<struct Model tag=:human, name="mami", age=15>
# create_human(name: name, age: age)
```

### デバッグ出力として利用する

```ruby
class Hash
	# 適当なデバッグ出力用メソッド
	def debug_output
		each { |key, value|
			puts "#{key}: #{value}"
		}
	end
end

def create(name, age)
	# 引数を確認するためのデバッグ出力
	%h(name age).debug_output
end

name = "homu"
age = 14
create(name, age)
# output:
# name: homu
# age: 14
```

## その他

* キーは Symbol で定義 → String 版もあったほうがよいだろうか
* 式展開のみ実装 → `%i` みたいな式展開を行わないでほしいユースケースが思いつかなかった
* なぜ `%h` という名前? → `Hash` だから…


以上、任意の変数名から Hash を展開する `%h` 記法の提案でした。
ご意見等あればコメント頂けると助かります。


## 関連するチケット

https://bugs.ruby-lang.org/issues/11105
https://bugs.ruby-lang.org/issues/14579
https://bugs.ruby-lang.org/issues/13137


---Files--------------------------------
hash_expand.patch (7.3 KB)


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-dev:50777] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash
       [not found] <redmine.issue-14973.20180807151247@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2018-08-09  6:55 ` [ruby-dev:50616] " knu
@ 2019-01-30 19:13 ` blake.h.l.west
  3 siblings, 0 replies; 4+ messages in thread
From: blake.h.l.west @ 2019-01-30 19:13 UTC (permalink / raw)
  To: ruby-dev

Issue #14973 has been updated by blakewest (Blake West).


I just want to +1 this. I think it's a great idea, and had raised it independently in [15236](https://bugs.ruby-lang.org/issues/15236). It doesn't seem like Matz has given an opinion on it though either here or in 15236. Can we bump this to see what his thoughts are? What's the best way to do that? Thanks - Blake

----------------------------------------
Feature #14973: Proposal of percent literal to expand Hash
https://bugs.ruby-lang.org/issues/14973#change-76596

* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
## 概要

変数名から `{ 変数名: 変数の値 }` という Hash を定義するための %記法の提案です。
以前からちょくちょく[提案されていた](https://bugs.ruby-lang.org/issues/14579)

```ruby
x = 1
y = 2
h = {x:, y:}
p h #=> {:x=>1, :y=>2}
```

のような ES6 ライクな構文を `{}` 構文ではなくて %記法で定義するものになります。


## 仕様

```ruby
hoge = 1
foo = 2
bar = 3

# スペース区切りの変数名をキー、変数の値を Hash の値として展開する
%h(hoge foo bar) # => { hoge: 1, foo: 2, bar: 3 }
```

これは以下と同等の処理になります。

```ruby
hoge = 1
foo = 2
bar = 3

{ hoge: eval("hoge"), foo: eval("foo"), bar: eval("bar") } # => { hoge: 1, foo: 2, bar: 3 }
```

### ローカル変数以外

内部で `eval` を使用しているので、そのコンテキストで評価できればローカル変数以外も使用することが出来ます。

```ruby
def meth
	"meth"
end

@hoge = 42
Foo = "str"

p %h(meth @hoge Foo $stdout)
# => {:meth=>"meth", :@hoge=>42, :Foo=>"str", :$stdout=>#<IO:<STDOUT>>}
```

キーは変数名そのままです(`$` や `@` がついたまま。


### 重複したキーがある場合

キーが重複している場合、`{}` と同様に2回目以降は無視されます。

```ruby
hoge = 42
foo = "str"

%h(hoge foo hoge)
# => {:hoge=>42, :foo=>"str"}
```


### キーの変数が存在しない場合

```ruby
hoge = 42
foo = "str"

%h(hoge foo bar)
# Error: undefined local variable or method `bar' for main:Object (NameError)
```


### Hash 内で展開

Hash なので `**` で展開できます。

```ruby
hoge = 42
foo = "str"

{ bar: "bar", **%h(hoge foo) }
# => {:bar=>"bar", :hoge=>42, :foo=>"str"}
```

## 式展開

`%I` などと同様に式展開を行います。

```ruby
hoge = 42
foo = "hoge"

%h(#{foo})
# => {:hoge=>42}
```


## ユースケース

### キーワード引数に渡す

```ruby
Model = Struct.new(:tag, :name, :age, keyword_init: true)

def create_human(name:, age:)
	# ** で Hash を展開して渡す
	Model.new(tag: :human, **%h(name age))
	# Model.new(tag: :human, name: name, age: age)
end

name = "mami"
age = 15
# 変数をまとめて渡す
create_human(%h(name age)) # => #<struct Model tag=:human, name="mami", age=15>
# create_human(name: name, age: age)
```

### デバッグ出力として利用する

```ruby
class Hash
	# 適当なデバッグ出力用メソッド
	def debug_output
		each { |key, value|
			puts "#{key}: #{value}"
		}
	end
end

def create(name, age)
	# 引数を確認するためのデバッグ出力
	%h(name age).debug_output
end

name = "homu"
age = 14
create(name, age)
# output:
# name: homu
# age: 14
```

## その他

* キーは Symbol で定義 → String 版もあったほうがよいだろうか
* 式展開のみ実装 → `%i` みたいな式展開を行わないでほしいユースケースが思いつかなかった
* なぜ `%h` という名前? → `Hash` だから…


以上、任意の変数名から Hash を展開する `%h` 記法の提案でした。
ご意見等あればコメント頂けると助かります。


## 関連するチケット

https://bugs.ruby-lang.org/issues/11105
https://bugs.ruby-lang.org/issues/14579
https://bugs.ruby-lang.org/issues/13137


---Files--------------------------------
hash_expand.patch (7.3 KB)


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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-01-30 19:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-14973.20180807151247@ruby-lang.org>
2018-08-07 15:12 ` [ruby-dev:50610] [Ruby trunk Feature#14973] Proposal of percent literal to expand Hash manga.osyo
2018-08-07 16:07 ` [ruby-dev:50611] " shevegen
2018-08-09  6:55 ` [ruby-dev:50616] " knu
2019-01-30 19:13 ` [ruby-dev:50777] " blake.h.l.west

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).