「Crystal」の版間の差分
削除された内容 追加された内容
タグ: 2017年版ソースエディター |
→制御構造: Crystalの実情に合わせて変更 タグ: 2017年版ソースエディター |
||
451 行
'''[[w:制御構造|制御構造]]'''(せいぎょこうぞう、''control flow'')とは、「順次」「分岐」「反復」という基本的な処理のことを言います。
{{コラム|
制御構造は「条件式」が真であるか偽であるかによって分岐や反復の振る舞いが変わります。
では「条件式」が真・偽はどの様に決まるのでしょう?
なので <code>0</code> も <code>[]</code>(空のArray) も <code>{}</code>(空の
}}
=== 条件分岐 ===
==== if ====
'''[[w:if|if]]'''は条件式によって実行・否を切り替える構造構文で、評価した式の値を返すので条件演算子でもあります。
;
a = 0.0 / 0.0
478 行
end
p! (
if a < 0
"minus"
491 行
</syntaxhighlight>
;表示結果:<syntaxhighlight lang="text">
NaN
(if a < 0
"minus"
else
if a > 0
"plus"
else
if a == 0
"zero"
else
a
end
end
end) # => NaN
</syntaxhighlight>
:; elsif節:ifは、オプショナルな elsif 節を設け、条件式が偽であった時に別の条件に合致した処理を実行させることが出来ます。
499 ⟶ 511行目:
==== 後置のif ====
;
n = 0
511 ⟶ 523行目:
</syntaxhighlight>
==== unless
'''unless
;
a = 0.0 / 0.0
530 ⟶ 542行目:
==== 後置のunless ====
;
n = 0
545 ⟶ 557行目:
caseは、複数の条件式によって処理を降る分ける用途の為に用意されています。
;
n = 2
558 ⟶ 570行目:
puts "other"
end
p! (
case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end
)
</syntaxhighlight>
;表示結果:<syntaxhighlight lang="text">
two
(case n
when 1
"one"
when 2
"two"
when 3
"three"
else
"other"
end) # => "two"</syntaxhighlight>
:C言語系のswitch文に慣れた人はbreakがないことに気がつくと思います。Crystalのcaseはfall throughしませんし、fall throughさせる方法もありません。
===== when節が定数でなく式を受付ける事を使ったトリック =====
[[#if|if]]を使ったコードをcaseに書き換えてみましょう。
;
a = 0.0 / 0.0
case true
when a < 0
when a > 0
when a == 0
else
end
p! (
case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end
)
</syntaxhighlight>
;表示結果:<syntaxhighlight lang="text">
NaN
(case true
when a < 0
"minus"
when a > 0
"plus"
when a == 0
"zero"
else
a
end) # => NaN
</syntaxhighlight>
このコードは when 節の式の値とcaseの式を <code>===</code> で比較し、最初に一致した when に対応する文が実行される事を利用しています。
589 ⟶ 646行目:
=== 繰返し ===
==== 繰返し構文 ====
===== while
while文(ホワイル
;構文:<syntaxhighlight lang=
while 条件式
:
end
</syntaxhighlight>
: Rubyと違い、条件式の後ろに <code>do</code> をつけることは
;
i = 0
p! (
while i < 10
p! i
i += 1
break i if i > 5
end
)
</syntaxhighlight>
: 2行目の <code>i < 5</code>が真の間、次の2行を繰返します。
: 4行目の <code>i += 1</code> は <code>i = i + 1</code> の構文糖
;実行結果:<syntaxhighlight lang="text">
(while i < 10
p!(i)
i = i + 1
if i > 5
break i
end
end)# =>
i # => 0
i # => 1
i # => 2
i # => 3
i # => 4
i # => 5
6
</syntaxhighlight>
===== until =====
until(アンティル
;構文:<syntaxhighlight lang=
until 条件式 [ do ]
文1
635 ⟶ 704行目:
: <code>do</code> は省略できます。
;
i = 0
until i == 3
puts i
i += 1
649 ⟶ 718行目:
</syntaxhighlight>
===== for
==== Rangeオブジェクト
Rangeオブジェクトは、整数の区間を表し範囲演算子 <code>開始 ... 終了</code> で生成します。
;コード:<syntaxhighlight lang=
rng = 1..3
puts rng.class
rng.each do | n |
puts "
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Range(Int32, Int32)
1番
2番
3番
</syntaxhighlight>
==== Arrayオブジェクト
Arrayオブジェクトは、任意の
配列式<code>[要素1, 要素2, … 要素n]</code> で生成します。
;
animals = ["ネコ", "金魚", "ハムスター"]
puts animals.class
animals.each do | animal |
puts "動物 #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Array(String)
動物
動物 金魚
動物 ハムスター
</syntaxhighlight>
====
また、キーが Symbol の場合
;
animals = {cat: "ネコ", gold_fish: "金魚", hamster: "ハムスター"}
puts animals.class
animals.each do | en, animal |
puts "動物 #{en}: #{animal}"
end
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
NamedTuple(cat: String, gold_fish: String, hamster: String)
動物 cat: ネコ
動物 gold_fish: 金魚
714 ⟶ 779行目:
</syntaxhighlight>
このように、
===== loop
loop、ありません。
while true で代用します。
;
i = 1
while true
puts "0b%b" % i
i <<= 1
break if i > 2**
end
</syntaxhighlight>
746 ⟶ 804行目:
0b100000000
</syntaxhighlight>
:5行目の、<code>break if i > 2**
:このコードは、
==== イテレーターメソッド ====
===== Integer#times =====
Integer#timesは与えられたブロックをオブジェクトの示す整数値回くりかえします。
:コード<syntaxhighlight lang=
3.times{ puts
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
799 ⟶ 820行目:
</syntaxhighlight>
;繰返したい処理が2行以上ある場合:<syntaxhighlight lang=
3.times {
puts
puts
puts
}
</syntaxhighlight>
817 ⟶ 838行目:
</syntaxhighlight>
;
3.times do |i|
puts "#{i}の倍は#{2 * i}"
828 ⟶ 849行目:
</syntaxhighlight>
;ブロックを伴わないtimesメソッド:<syntaxhighlight lang=
iter = 3.times
puts iter.class
837 ⟶ 858行目:
</syntaxhighlight>
;実行結果:<syntaxhighlight lang="text">
Int::TimesIterator(Int32)
0
1
2
</syntaxhighlight>
: Integer#times にブロックを渡さないと、
:
== 脚註 ==
|