Ruby 初心者スレッド Part 61 [無断転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
2017/08/25(金) 15:59:11.22ID:HsL9LVKJ
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。
質問するときは、OSやRubyのバージョン、エラーメッセージを書いたほうがいいお
Ruby on RailsについてはWEBプログラミング板で

前スレ
Ruby 初心者スレッド Part 60
https://mevius.2ch.net/test/read.cgi/tech/1493398918/

るりまサーチ (リファレンス検索)
http://rurema.clear-code.com/

Rubyist Magazine - るびま
http://jp.rubyist.net/magazine/

逆引きRuby
http://www.namaraii.com/rubytips/
2017/08/25(金) 16:05:20.69ID:0nrK3Ckt
大規模障害記念
2017/08/25(金) 16:05:48.85ID:HsL9LVKJ
たのしいRuby 第5版、2016

Effective Ruby、2015

メタプログラミング Ruby 第2版、2015

Rubyのしくみ、2014

改訂3版 基礎 Ruby on Rails、黒田努・佐藤和人、2015

リファクタリング:Rubyエディション、2010
2017/08/25(金) 16:10:23.56ID:HsL9LVKJ
ギリセーフで間に合った
2017/08/25(金) 16:11:37.65ID:sLUvaIRs
前スレ>>997,999
ありがとうございます。

自分のレベル的に997の方しか理解できていませんが、
999の方もがんばって読み解いてみます。
6デフォルトの名無しさん
垢版 |
2017/08/25(金) 16:12:33.08ID:BwHFndLq
each_with_object
なんて初めて見た。


a=[[1,2],3,4,5,[6,7],8,[9,10],[11,12],[13,14]]

b = a.each_with_object([[],[]]) {|(x, y), acc| acc[0] << x; acc[1] << (y || x) }
p b # => [[1, 3, 4, 5, 6, 8, 9, 11, 13], [2, 3, 4, 5, 7, 8, 10, 12, 14]]
7デフォルトの名無しさん
垢版 |
2017/08/25(金) 16:18:41.59ID:BwHFndLq
evens = (1..10).each_with_object([]) {|i, a| a << i*2 }
# => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

each_with_objectってのは引数一個(空の配列)とブロックを取るみたい。
ブロックには、引数が2つ渡り、最初は、列挙される要素、2番目は引数(空の配列)が渡るらしい。

ブロックの戻値がeach_with_objectの戻値かな?
8デフォルトの名無しさん
垢版 |
2017/08/25(金) 16:25:39.04ID:BwHFndLq
a=[[1,2],3,4,5,[6,7],8,[9,10],[11,12],[13,14]]
p a

a.each{|(x, y)| puts "x = " + x.to_s + "y = " + y.to_s}

このtupleみたいな(x, y)ってのは何だ?
Rubyにtupleがあるのか?
2017/08/25(金) 16:26:35.62ID:4MOWRfGQ
ブロック中での最後の評価値、じゃないのがこれの使い易いところ
戻り値には、each_with_object(ここのオブジェクト)を返す

injectでやろうとして
b = a.inject([[],[]]) {|acc, (x, y)| acc[0] << x; acc[1] << (y || x); acc}
ブロックの最後でこうやってaccを返そうとして頑張っちゃうような時には考えたい
10デフォルトの名無しさん
垢版 |
2017/08/25(金) 16:30:33.90ID:BwHFndLq
よく判らんが、要素2個の配列をブロックの引数で(x, y)って受け取れば、
2個の要素はx,yとして受け取れるらしい。
11前スレ996
垢版 |
2017/08/25(金) 16:55:24.12ID:sLUvaIRs
aの配列の個数が変わる場合があるので、とりあえず以下のようにしてみたのですがrslt1とrslt2で結果が異なるのは何故ですか?
tobj==[[],[]]はtrueと出ます。

a=[[1,2],3,4,5,[6,7],8,[9,10],[11,12],[13,14]]
tobj=[[]]*2
rslt1 = a.each_with_object([[],[]]) {|x,tary|; tary.each_with_index{|n,i| x.instance_of?(Array) ? tary[i]<<x[i] : tary[i]<<x}}
rslt2 = a.each_with_object(tobj) {|x,tary|; tary.each_with_index{|n,i| x.instance_of?(Array) ? tary[i]<<x[i] : tary[i]<<x}}
12前スレ996
垢版 |
2017/08/25(金) 17:00:35.79ID:sLUvaIRs
すみません。上のは不要なセミコロンが入っていました。(動作は問題ないみたいですが)

a=[[1,2],3,4,5,[6,7],8,[9,10],[11,12],[13,14]]
tobj=[[]]*2
rslt1 = a.each_with_object([[],[]]) {|x,tary| tary.each_with_index{|n,i| x.instance_of?(Array) ? tary[i]<<x[i] : tary[i]<<x}}
rslt2 = a.each_with_object(tobj) {|x,tary| tary.each_with_index{|n,i| x.instance_of?(Array) ? tary[i]<<x[i] : tary[i]<<x}}
p rslt1,rslt2
2017/08/25(金) 17:06:01.66ID:W3qddKKH
Rubyの初め方

ルビィの冒険

たのしいRuby、初めてのRuby

パーフェクトRuby

Rubyベストプラクティス
EffectiveRuby
メタプログラミングRuby1版or2版
Rubyによるデザインパターン

リファクタリングRubyエディション
Rubyのしくみ。

ウェブアプリ方面
パーフェクトRubyonRails
RubyonRails5アプリケーション・プログラミング
Docker教科書
JapaScript本格入門第二版
入門Git
GitHub実践入門
SQL 第2版 ゼロからはじめるデータベース操作
達人に学ぶ SQL徹底指南書
SQLアンチパターン
14デフォルトの名無しさん
垢版 |
2017/08/25(金) 17:51:40.95ID:HsL9LVKJ
リファクタリングRubyエディション
Rubyのしくみ

このふたつは必読
2017/08/25(金) 18:32:17.61ID:w/d6Mddl
>>前スレ989
それ継承でなくて上書きがダメって言ってるだけじゃん
Objectクラス継承しちゃうんだからもうオブジェクト指向言語使うのやめなよ
2017/08/25(金) 18:48:50.81ID:W3qddKKH
>>13
最初からwebアプリ(Rails)を作りたい人は
ルビィの冒険

たのしいRuby、初めてのRuby

パーフェクトRuby

パーフェクトRubyonRails
達人に学ぶ SQL徹底指南書
達人に学ぶ DB設計徹底指南書
SQLアンチパターン

テスト駆動開発をやりたい人は
Railsチュートリアル
はじめて学ぶソフトウェアテスト技法
Everyday Rails - RSpecによるRailsテスト入門
2017/08/25(金) 19:18:38.80ID:3NyVHrhs
>>12
そりゃあんた2次元配列の初期化の基本でしょ。
tobj[0].object_id == tobj[1].object_id なんだから。
tobj = Array.new(2).map([]) とでもしないと。
2017/08/25(金) 19:25:54.88ID:3NyVHrhs
>>10
x, y = [1, 2]
# x = 1; y = 2

x, y = 3
# x = 3; y = nil
を考えれてみれば分かる。
2017/08/25(金) 19:27:54.09ID:UfR6nGBm
Rubyに多次元配列は存在しない
とかいう例のアレにも通じるアレだな

Array#*は単純にレシーバを引数回繰り返した結果を返す(値は複製しない)
複製しないってことは同じ配列がいくつも繰り返されるだけだ
つまり [[]]*2 と [[],[]] は違う
2017/08/25(金) 20:37:35.28ID:rKeka8MH
a=[[1,2],3,4,5,[6,7],8,[9,10],[11,12],[13,14]]
a.map {|e| [[e].flatten[0], [e].flatten[-1]] }.transpose
=> [[1, 3, 4, 5, 6, 8, 9, 11, 13], [2, 3, 4, 5, 7, 8, 10, 12, 14]]
21デフォルトの名無しさん
垢版 |
2017/08/25(金) 21:01:41.73ID:rKeka8MH
[a.map {|(e)| e }, a.map {|(*,e)| e }]
=> [[1, 3, 4, 5, 6, 8, 9, 11, 13], [2, 3, 4, 5, 7, 8, 10, 12, 14]]
2017/08/25(金) 21:09:45.04ID:rKeka8MH
[a.map {|(e,*)| e }, a.map {|(*,e)| e }]
=> [[1, 3, 4, 5, 6, 8, 9, 11, 13], [2, 3, 4, 5, 7, 8, 10, 12, 14]]
こっちのほうがきれい >>21は撤回で
2017/08/25(金) 21:31:15.78ID:SZeQgZta
カッコ要らないよ
[a.map {|e,*| e }, a.map {|*,e| e }]
2017/08/25(金) 21:58:40.29ID:rKeka8MH
>>23
恐縮です
2017/08/25(金) 22:46:54.39ID:teISJdbp
>>10
メソッドやブロックの引数の受け取り方は多重代入と似た挙動になってるから
入れ子になった配列も展開して変数に受け取ることもできる

def test(a, (b, (c, d)))
 ……
end

test 1, [2, [3, 4]]
2017/08/25(金) 22:56:33.15ID:UfR6nGBm
コードゴルフ(もどき)はあまり好ましいことではないように思える
初心者スレであるから特に
splat*を書いてしまったら立ち止まるべきかと
2017/08/26(土) 00:10:52.42ID:azDqTcfP
>>10
Destructuringだね

多重代入は括弧により、ネストした配列の要素を代入することもできます。
https://docs.ruby-lang.org/ja/2.4.0/doc/spec=2foperator.html#multiassign
http://tony.pitluga.com/2011/08/08/destructuring-with-ruby.html
2017/08/26(土) 00:16:16.83ID:Q9D9720h
うむ
尤もだ
29デフォルトの名無しさん
垢版 |
2017/08/26(土) 00:18:15.51ID:6TCzEPsc
>>26
好ましくないが、楽しいので初心者向き。
30デフォルトの名無しさん
垢版 |
2017/08/26(土) 00:23:16.07ID:6TCzEPsc
>>18
うぅーん。よく判らん。
Rubyの多重代入が、ブロック引数にも使えるって事なのか?
2017/08/26(土) 00:30:44.39ID:Q9D9720h
>>27
上のリンク先の多重代入の説明間違ってるな
2017/08/26(土) 00:31:33.66ID:GUwpgiyr
カンマで区切る代入はRubyの魔境のひとつなので半端に深入りするのも半端に慣れるのも事故のもとだからやめといたほうがいいかも
33デフォルトの名無しさん
垢版 |
2017/08/26(土) 01:28:41.95ID:8HsFh7FA
多重代入でもハッシュが使えればなーって思うことがたまにある

(x:, y: 1, z: 1.5) = { x: -1 }
2017/08/26(土) 01:33:58.36ID:N4fvc+FV
式の評価の順番がわけわかめになるのでやめちくり><
2017/08/26(土) 01:44:30.12ID:azDqTcfP
>>33
それはHash#mergeじゃいかんの?

hash = {x:nil, y:1, z:1.5}
hash.merge x:-1
=> {:x=>-1, :y=>1, :z=>1.5}
36デフォルトの名無しさん
垢版 |
2017/08/26(土) 07:51:03.88ID:6TCzEPsc
>>32
ホントだ。魔境だ。変な仕様だ。

多重代入は括弧により、ネストした配列の要素を代入することもできます。

(foo, bar), baz = [1, 2], 3 # foo = 1; bar = 2; baz = 3
37デフォルトの名無しさん
垢版 |
2017/08/26(土) 07:53:51.24ID:6TCzEPsc
そういえばMatz自身が魔境だと言う動画を見たことある。
Matz 多重代入 で検索。

$変数も魔境だ。C言語の関数ポインタの宣言の読み方も魔境だ。
SwiftのStringも魔境だ。


おっと、失礼!
38デフォルトの名無しさん
垢版 |
2017/08/26(土) 08:14:32.01ID:6TCzEPsc
多重代入、trickyすぎる。


files = ['Gemfile', 'LICENSE.txt', 'README.md', 'Rakefile', 'bin', 'lib', 'maliq.gemspec', 'pkg', 'spec']

多重代入+括弧で解決します。

(gemspec, *_), files = files.partition { |f| f.match(/¥.gemspec$/) }
gemspec # => "maliq.gemspec"
files # => ["Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin", "lib", "pkg", "spec"]
39デフォルトの名無しさん
垢版 |
2017/08/26(土) 13:07:20.00ID:6TCzEPsc
>>37
これが出典ね!

http://melborne.github.io/2013/03/04/ruby-trivias-you-should-know-4/
2017/08/26(土) 18:34:53.74ID:8HsFh7FA
>>35
それだとその後に
x, y, z = hash[:x], hash[:y], hash[:z]
ってやるか
x, y, z = hash.values_at(:x, :y, :z)
ってやった上に必須キー・不正なキーの確認処理が必要になるじゃない

((x1:, y1:, color1: 0xffffffff), (x2:, y2:, color2: 0x00ffffff)) = obj
みたいに配列中のハッシュも多重代入で済ませられたらなってのが動機

……新しい魔境ができそう
2017/08/26(土) 20:25:10.89ID:Q9D9720h
長年の謎だったがアスタリスクのことをスプラットとも言うのか
2017/08/26(土) 20:31:00.33ID:0rCQx/Jc
いやアスタリスクはアスタリスクだよ
引数展開をsplatと呼ぶ
それに使われるときの演算子だからsplat
2017/08/26(土) 20:48:19.79ID:azDqTcfP
>>40
うん、すまんが何を実現したいか理解できんかった
44デフォルトの名無しさん
垢版 |
2017/08/26(土) 21:22:20.08ID:6TCzEPsc
>>41
splat = ビシャ
スプラトゥーンってゲーム流行ってるらしいけど、俺は興味無い。
45デフォルトの名無しさん
垢版 |
2017/08/26(土) 21:32:43.71ID:CwpB94hG
>>32,36
魔境?、よくわからんけど ML や Haskell といったモダンな関数型言語にある
タプルのパターンマッチングをRubyが部分的に導入した(パクった)だけでは?

たとえば SML(Standard ML) だと、以下は魔境でも魔術でもなんでもなく
単なるパターンマッチングの初歩でしかない

- val ((x, y), z) = ((1, 2), 3); (* 先頭の ‘-‘ はSML/NJのプロンプト *)
val x = 1 : int (* 以下はSML/NJ の応答 *)
val y = 2 : int
val z = 3 : int

少なくとも、これをSMLの世界で魔境やら多重代入と呼ぶ人は存在しない
君たちを見ていると、何やら未開の土人がテレビという文明に接して、
それを魔境の道具などと謎に満ちた深淵な事象に認識してしまう映像を思い出す
2017/08/26(土) 21:42:19.80ID:0rCQx/Jc
ただの変数リテラル代入を魔境と呼んでる人はいないと思う
2017/08/26(土) 22:03:00.31ID:zlhz7EzI
Prologなんか言語自体が
パターンマッチングで動作してて
全部魔境だからな
48デフォルトの名無しさん
垢版 |
2017/08/26(土) 22:03:41.96ID:CwpB94hG
>>46
モダンな関数型言語のパターンマッチングが単なる変数への代入に限定されると
思い込んでるってことは、君も彼らと同じく未開の土人なんだろな
そんなのネットで調べればすぐにわかることなのに気の毒な
49デフォルトの名無しさん
垢版 |
2017/08/26(土) 22:26:45.42ID:CwpB94hG
>>47
Prolog だと>>45の例は以下のようになる

?- ((X, Y), Z) = ((1, 2), 3). % 先頭の ‘?-‘ は SWI-Prolog のプロンプト
X = 1, % 以下は SWI-Prolog の応答
Y = 2,
Z = 3.

なお ML や Haskell といった関数型言語(および Ruby)のパターンマッチングは
変数と値の代入に限定されるけど、Prolog では変数と変数のマッチも許容され、
それを単一化(ユニフィケーション)と呼び、論理型言語の特質の一つになっている

まあそれを魔境と捉えるのはその人しだいだし、確かに初対面では魔境にしか
見えないのも仕方ないのかもしれない
でも自分にとっては、Lisp の caadr やら cadar やらに嫌気がさしていたから、
なんて(人に)優しい構文なんだと Prolog に入れ込む理由の
大きな要因の一つになっていた

同じく、Ruby のケースも導入されたのは 1.8 の頃だと思うけど、
自分はそれを肯定的に捉えている
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況