約 66,743 件
https://w.atwiki.jp/kijokazu/pages/12.html
フィードバック制御とは 制御理論の教科書を読むと、いろいろな制御が紹介されていますが、基本はフィードバック制御に集約されます。これを確実に理解することが、制御理論の習得の近道だと著者は考えています。それでは、登場人物の小松君と一緒に制御理論に触れてみましょう。 研究室の風景 ある大学の工学部電気系学科の研究室に、卒論生として配属された4年生の小松は、卒論テーマが苦手な制御になってしまった。制御理論の教科書を引っ張り出して、復習に取り組んでいるが・・・。 小松「うーん。わからない・・・。やっぱり制御理論は苦手だ・・・。」 野原「小松君は制御理論の勉強ね。感心。感心。」 後ろから覗き込んだのは先輩の野原。小松の指導を担当する大学院修士課程2年生、女性である。 小松「あっ、野原先輩。制御理論の勉強って、どこから手をつければよいのでしょうか。講義の単位は取得したのですが、あまり十分に理解していなくて・・・。」 野原「それは自分で頑張るしかないでしょ。私も研究室に配属してから勉強し直しました。でも小松君の言うように、制御理論のとっつきにくさはわかる気もするけど・・・。」 藤田「こんにちは。おっ、野原さん。卒論生の指導ですか。」 研究室に入ってきたのはOBの藤田。電機メーカーに勤務する社会人2年目。リクルーター活動で研究室を頻繁に訪問している。 野原「藤田先輩。研究室を訪問されるなら事前に連絡してくださいよ。」 藤田「思いつきで立ち寄りました。やはり会社より研究室が落ち着きますね。あっ、はじめまして。OBの藤田と申します。在学中は野原さんと一緒に制御工学を専攻していました。」 小松「学部4年生の小松です。卒論テーマは制御で、野原先輩の下についています。」 藤田「勉強中にお邪魔しました。そうだ、せっかくだから3人で制御理論の勉強会でもやろうか。」 野原「先輩もお忙しいのに、申し訳ないですよ・・・。」 藤田「たまには気分転換で。そう言う野原さんが、一番やる気がありますから。」 小松「ありがとうございます。よろしくお願いします。」 電車がホームに停まる 藤田「さて、制御の基本はフィードバック制御に集約されます。小松君はどんなイメージを持っていますか。」 小松「えーと、例えば自動車を運転している時、スピード違反にならないように、速度メーターをチェックしながらアクセルを調整します。それで速度が変化して、またアクセルを調整します。その繰り返しで速度を制御するイメージです。」 藤田「おっ、さすがですね。それでは、この制御系のゲインはどこに相当するでしょうか。」 小松「何だろう・・・。アクセル調整かな。」 藤田「正解です。この場合は運転手の性質も含みますね。速度の変化に対してアクセル調整が少ないと、反応が遅い運転になります。逆にアクセル調整が大きいと、速度がふらついて、乗り心地の悪い運転になると。」 野原「つまり運転が上手な人は、最適ゲインに近いということですね。」 藤田「そういうことです。次は電車がホームにぴったり停まる動作を考えましょうか。これもフィードバック制御に当てはまります。」 小松「この場合は電車の運転手が、ホームの停止位置との距離を確認しながら、ブレーキを調整します。」 藤田「でも電車がスピードを出していたら、ブレーキが間に合わず、停止位置をオーバーするよ。」 野原「距離だけでなく速度も意識しないと。スピードが出ていたら早めにブレーキをかける。あっ、これは微分ゲインの役割なのかな。」 藤田「速度を意識することで、確実に運転手の反応は良くなりますね。距離の微分が速度ですから、微分ゲインとも見なせるでしょう。」 小松「電車の運転手は、複数のゲインを持っているのですね。」 藤田「人間ほど高度なコントローラはないと思います。それを機械にやらせるのは大変です。そのために制御理論が存在するのですよ。」 野原「藤田先輩、質問があります。さっきの電車の話で、積分ゲインは何に相当するのでしょうか。」 藤田「野原さん、また難しい質問を・・・。例えば電車が少しオーバーランしました。停止位置と距離が発生しています。それを時間で積分してみてください。」 野原「時間が経つにつれて、積分値が大きくなって・・・。なるほど、その積分値の増加が、電車を停止位置に修正したい、運転手の気持ちに相当するのですね。」 藤田「強引な説明ですが、まあそんな感じです。結局、停止位置ぴったりとならない限り、積分値の増加は抑えられません。すなわち、積分ゲインは偏差をつめる役割があるのです。」 小松「微分ゲインと積分ゲインの役割が、少しイメージできた気がします。先輩方の話は本当に勉強になります。」 鉄板の磁気浮上 <現在記述中>
https://w.atwiki.jp/kimh/pages/13.html
1.電気保全技術 3.PC制御 4.空気圧制御 5.高速カウンターACモータ制御 6.計算機リンク 7.プログラム表示機 8.ACサーボモータによる位置決め制御 9.FAセンサ 10.CCLink 10-2.CCLink2 12.PC制御(Ethernet) 13.ネットワーク基礎 ・基数変換 ・論理数学 14.ネットワーク ・network ・TCPIP 15.C言語
https://w.atwiki.jp/warningscratcher2/pages/106.html
制御のブロック ここでは「制御」のブロックについて解説していきます ジャンル 制御 対応 スプライトと背景 ブロックの効果と概要 双方対応 ○○秒待つ 指定された秒数のみ待つ 0秒が最短 ○○回繰り返す。 指定された回数このブロックの区切り内にあるスクリプトの行動を繰り返す 整数のみ入力できる ずっと このブロックの区切り内にあるスクリプトの行動をこのスクリプトを止める・スプライトの他のスクリプトを止めると言うブロックが実行される、また停止ボタンが押されるまで、永久に繰り返す。 もし なら 型のブロックの条件を満たしたときにのみこのブロックの区切りのスクリプトは実行される もし なら/でなければ 基本的には「もし なら」ブロックと動作は同等であるが、そうでない場合の区切りがある。 まで待つ 型のブロックの条件を満たすまで待機し続ける。 まで繰り返す このブロックの区切り内のスクリプトを繰り返し (すべてを止める・このスクリプトを止める・スプライトの他のスクリプトを止める) 三種類の動作を選んで実行させる。尚スプライトの他のスクリプトを止めるという設定以外はブロックを接続できないようになっている。内容は以下ほどである。 すべてを止める- その作品のスクリプト兼背景全ての行動を直ちに停止させる このスクリプトを止める- 実行されたスクリプトを直ちに停止させる スプライトの他のスクリプトを止める- 実行されたスプライト内の実行しているスクリプトを 除いた全てのスクリプトを直ちに停止させる ○○のクローンを作る 自身のクローン又は他スプライトのクローンを作ることが出来る。 出来たクローンは停止ボタンが押されるか、そのクローンに対し「このクローンを削除する」ブロックが実行されることのみ消せる 背景は他のスクリプトのクローン作製のみ可能 https //scratch.mit.edu/projects/657608734/参照 スプライトのみ対応 クローンされたとき 「○○のクローンを作る」が実行されたときそのスプライトが対象であった場合即時に実行できるイベントブロック クローンされた場合に本スプライトよりも一層後方に出現する https //scratch.mit.edu/projects/657608734/参照 このクローンを削除する 指定されたクローンを削除する。 https //scratch.mit.edu/projects/657608734/参照 裏技 名前
https://w.atwiki.jp/rigidchips/pages/58.html
概要 実践制御では、RigidChipsにおける制御をわかりやすい実例を交えて解説していきます。 Lua導入講座も旧RCWikiと運命を共にしたので、簡単ですがLua導入についても解説しています。 講座 実践制御0:Lua導入。導入・代入・_KEY関数・if構文など 実践制御1:Lua導入。テーブル変数・論理型・繰り返し構文など 実践制御2: 執筆中 シーケンス制御。スイッチ制御など 実践制御3:フィードバック制御。ON/OFF制御・P制御など 実践制御4: 執筆中 フィードバック制御。PI制御・PID制御など 実践制御4以降は予定されていません。執筆したい方はぜひどうぞ
https://w.atwiki.jp/jfdeo/pages/32.html
制御盤の構造・特性 構造下記材料に因り形成不燃性 難燃性 充電部位に対する保護 腐食の懸念対象に対し防食措置 付加構造制御盤用音響装置動作要因制御盤の電路異常 閉止弁の閉止 下記に因り警報音声 音響 復旧スイッチ消火動作状態を監視状態に復元 表示灯電源表示灯他 自動手動切換スイッチ自動式起動装置の付設設備が対象 自動・手動起動を切換 鍵等に因り動作 標示製造者名又は商標 製造年 型式番号 性能耐久性の具有 各種制約 電気的制約90~110[%]間の電源電圧変動に対する正常動作の保持 絶縁抵抗充電部外殻間が対象 DC500[V]の絶縁抵抗測定器にて測定 3[Ω]以上となる絶縁抵抗 絶縁耐力下記実行電圧の印加に対し絶縁状態の保持定格電圧が60[V]以下 500[V] 定格電圧が60[V]超、150[V]以下 1000[V] 定格電圧が150[V]超 定格電圧×2+2000[V] 下記付加条件に因り印加印加時間 1[min] 周波数 50・60[Hz]の正弦波への近似周波数 手動式起動装置の付設における制約操作箱の開放操作に因る作動遷移防護区画に対し起動装置を操作 音響警報装置の起動信号を発信 制御盤の作動遷移制御盤にて起動信号を受信 表示 音響警報に対し制御信号を発信 消火剤の放出操作に因る作動遷移対象防護区画に対し下記を実行換気装置を停止 自動閉鎖装置に因り開口部を閉鎖 設置放出表示灯の作動信号を発信 遅延時間の付加における動作遷移規定の時間待機 規定時間内における放出停止信号の受信に対し動作を停止 下記何れかの付設弁に対する開放信号を発信容器弁 放出弁 選択弁 付設時 2酸化炭素消火設備における追加制約制御盤にて下記動作を実行閉止弁における閉止信号の受信制御盤の構成音響警報装置を起動 表示 点滅表示の場合、上記音響警報装置の省略が可能 閉止弁における開放信号の受信表示 自動式起動装置の付設における制約起動装置の切換スイッチに因り自動・手動起動を変更 起動装置の起動方法を起動装置に発信し表示 感知器に対する相互動作前提条件下記を除く受信機の省略 受信器が感知器の火災信号を直接受信 感知器火災信号の受信時、下記動作を実行発信防護区画を表示 受信機に対し発信 消火剤の放出制御感知器からの火災信号の受信における動作遷移対象即時動作のハロン1301消火設備 他消火剤の採択消火設備 動作対象防護区画に対し下記の作動信号を発信音響警報装置 換気装置停止 自動閉鎖装置 遅延時間の実装における動作遷移遅延時間内における放出停止信号の受信に対し動作を停止 規定時間の経過後に下記の作動信号を発信容器弁の開放 選択弁の付設時における開放 手動起動状態への切換に対する動作遷移手動起動に準拠 障害対策 電路異常における動作遷移対象ハロン1301を除く消火設備 消火剤放出信号の受信電路 障害要因短絡動作遷移短絡の発生を表示 操作盤の付設時においては当該障害の発生信号を発信 制御盤用音響警報装置を起動 起動方法に因る動作遷移手動 手動式起動装置の付設における制約に準拠 自動 監視を保持 地絡前提条件両極の同時開閉に因る電路制御を除く 地絡における動作遷移地絡の発生を表示 操作盤の付設時においては当該障害の発生信号を発信 制御盤用音響警報装置を起動
https://w.atwiki.jp/kotechan/pages/29.html
魔法・制御系スキルについて -... 《制御系スキル》 ┃ ┃ ┣《メディテーション》(瞑想)(増強&制御&信仰系)〔前提スキル:無し 上限Lv:1 最大Lv:1〕 ┃ ┗┓ ・短時間の休息でMPを回復する技術。 ┃ ┃ ┃ ┃ ┃ ┣《スピリチュアルキャスティング》(精神詠唱)〔前提スキル:無し 上限Lv:(制御系÷5)+1 最大Lv:3〕 ┃ ┃ ・心の中でトゥルーワードをイメージして呪文を組み立てることで、超能力者呪文の詠唱や動作を簡略化してその力を発揮する技術。 ┃ ┃ ┃ ┏┛ ┣《クリアマインド》(頭脳明晰)(増強&制御系)〔前提スキル:無し 上限Lv:1 最大Lv:1〕 ┃ ┗┓ ・澄み切って冴え渡った精神が、魔術師・錬金術師・超能力者呪文のMP回復量を増大させる。 ┃ ┃ ┃ ┃ ┃ ┣《セルフコントロール》(自制心)〔前提スキル:《クリアマインド》《アブストラクション》 上限Lv:1 最大Lv:1〕 ┃ ┃ ・冷静沈着な意思と精神を制御する技術により、IRに+4のボーナス。 ┃ ┃ 精神系BSの回復チェックに+4のボーナス。 ┃ ┃ ┃ ┏┛ ┣《アブストラクション》(精神集中)〔前提スキル:無し 上限Lv:(制御系÷5)+1 最大Lv:2〕 ┃ ┗┓ ・戦闘時の緊張状態で高まった精神を集中させることにより、次のラウンドの呪文詠唱の効果を高める技術。 ┃ ┃ 精神集中を行った1ラウンドにつき、CLにスキルLv×4、クリティカル率にスキル×2のボーナスを得る。 ┃ ┃ ┃ ┃ ┃ ┣《セーフティキャスティング》(安定詠唱)〔前提スキル:《アブストラクション》《リチュアルマジック》 上限Lv:(制御系÷5)+1 最大Lv:3〕 ┃ ┃ ┃ ・呪文を巧く制御して、暴走する確率を抑える技術。 ┃ ┃ ┃ 呪文詠唱の際にファンブルのダイス目が出た場合、1シナリオ中にスキルLv回数まで振りなおすことができる。 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗《モービルキャスティング》(移動詠唱)〔前提スキル:《セーフティキャスティング》 上限Lv:(制御系÷5) 最大Lv:1〕 ┃ ┃ ┃ ・極めて安定した精神集中と呪文詠唱により、移動などを行いつつ呪文を唱えることを可能とする技術。 ┃ ┃ ┃ 〔メインアクション〕+〔パッシブアクション〕で呪文詠唱が可能となる。 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗《バトルキャスティング》(戦闘詠唱)〔前提スキル:《モービルキャスティング》 上限Lv:(制御系÷8) 最大Lv:1〕 ┃ ┃ ・乱戦の中でも自らの身を守りつつ、隙のない呪文詠唱を行う高度な技術。 ┃ ┃ 〔メインアクション〕のみで呪文詠唱が可能となる。 ┃ ┃ ┃ ┏┛ ┣《リチュアルマジック》(儀式魔法)〔前提スキル:無し 上限Lv:1 最大Lv:1〕 ┃ ┗┓ ・落ち着いた状況下において、時間をかけて呪文を唱えることにより失敗なく呪文の力を発動させる技術。 ┃ ┃ 非戦闘時に限り呪文詠唱に3ラウンドを用いることにより、詠唱判定の必要なく呪文を通常効果で発動させることができる。 ┃ ┃ ┃ ┃ ┃ ┣《エンチャント》(魔力付与)〔前提スキル:《リチュアルマジック》《マテリアルマジック》 上限Lv:(制御系÷5)+1 最大Lv:2〕 ┃ ┃ ┃ ・物品に魔力を付与して薬・スクロールなどの消費マジックアイテムを作成する技術。 ┃ ┃ ┃ 転じて、マジックアイテムを上手く使いこなす技術としても活用できる。 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗《パーマネンス》(永続化)〔前提スキル:《エンチャント》 上限Lv:(制御系÷8)+1 最大Lv:2〕 ┃ ┃ ・物品に魔力を付与して、不変的な魔力を持つマジックアイテムを作成する技術。 ┃ ┃ 転じて、マジックアイテムを上手く使いこなす技術としても活用できる。 ┃ ┃ ┃ ┏┛ ┣《マテリアルマジック》(触媒魔法)〔前提スキル:無し 上限Lv:(制御系÷2)+1 最大Lv:3〕 ┃ ┃ ・魔法の触媒を用いて、呪文の効果を高める技術。 ┃ ┃ ┃ ┃ ┃ ┗《マジックソード》(魔法剣)〔前提スキル:《マテリアルマジック》 上限Lv:(制御系÷5)+1 最大Lv:3〕 ┃ ・魔法剣とはマジックナイトによって確立された戦闘技術で、秘術を用いて、武器に一時的な魔力の刃を付与するものである。 ┃ ┃ ┣《スペルイクステンション》(呪文延長)〔前提スキル:無し 上限Lv:(制御系÷2)+1 最大Lv:4〕 ┃ ┃ ・呪文の持続時間や射程距離を延長する技術。 ┃ ┃ ┃ ┃ ┃ ┣《エリアコントロール》(範囲制御)〔前提スキル:《スペルイクステンション》 上限Lv:(制御系÷5)+1 最大Lv:3〕 ┃ ┃ ┃ ・範囲呪文を用いる際に乱戦中の味方を避けて、敵のみを攻撃する技術。 ┃ ┃ ┃ 呪文の範囲に含まれている対象のうち、(スキルLv)×2体までの任意の目標を避けて呪文を発動させることができる。 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗《スペルエンラージ》(呪文拡大)〔前提スキル:《エリアコントロール》 上限Lv:(制御系÷4) 最大Lv:5〕 ┃ ┃ ・呪文の効果範囲を拡大する技術。 ┃ ┃ 呪文の効果範囲が「m」で表記されている呪文に限り、「(スキルLv)×2m」以下の任意の値で効果範囲を広げることができる。 ┃ ┃ ┃ ┃ ┃ ┗《アディショナルエフェクト》(付加効果)〔前提スキル:《スペルイクステンション》 上限Lv:(制御系÷10) 最大Lv:2〕 ┃ ・余分にMPを消費することにより、呪文に付加効果を発生させる。 ┃ 該当する呪文のMPを3点消費することにより(消費MP+2)、呪文データに記載されている付加効果を任意で発生させることができる。 ┃ ┃ ┗《ファストチャント》(高速詠唱)〔前提スキル:無し 上限Lv:(制御系÷2)+1 最大Lv:3〕 ┗┓ ・高レベル呪文を淀みなく素早く詠唱する技術。 ┃ 呪文を唱える際のイニシアチブペナルティ(呪文Lv1につき、INIに-1のペナルティを受ける)をスキルLv×2だけ緩和。 ┃ ┃ ┣《カウンタースペル》(対抗呪文)〔前提スキル:《ファストチャント》戦術系《タイムリーアクション》 上限Lv:(制御系÷8) 最大Lv:2〕 ┃ ・敵の攻撃に対抗する属性の呪文をぶつけることにより、その効果を相殺、減少させる技術。 ┃ ┏┛ 戦術系《タイムリーアクション》 <めもめも> 《マジックソード》は射程距離に《スペルイクステンション》Lvを追加。基本はダメージ魔法剣メインの用法で。
https://w.atwiki.jp/javamock/pages/51.html
制御構文 制御構文とはプログラムの処理の流れを制御するものです。 条件分岐処理や繰り返し処理などを制御します。 条件分岐にはifやswitchを使います。 繰り返し処理にはforやwhileを使います。 条件分岐 ifについて → if switchについて → switch 繰り返し処理 whileについて → while forについて → for その他 制御構文 breakについて → break continueについて → continue returnについて → return
https://w.atwiki.jp/gensou_utage/pages/672.html
制御棒 No.2910 制御棒 サポートカード 配置:スペル 条件:空 呪力1 このサポートは、使用条件に『空』が含まれているスペルにのみ配置できる。 [戦闘フェイズ]常時 このサポートが配置されたスペルは「攻撃+1」を得る。 自分のリーダーが『空』の場合、更に「命中+1」を得る。 [戦闘フェイズ]常時 このサポートが配置されたスペルでの戦闘中、自分のリーダーにスペルによるダメージが与えられる場合、そのダメージに+1する。 イラスト:天空すふぃあ 考察 考察の入力。必須ではない。 公式FAQ Q: 「制御棒」を配置したスペルが「乾坤一擲」を配置されたスペルで迎撃され命中した場合 乾坤一擲によるダメージも+1されるのでしょうか? それとも乾坤一擲の効果が戦闘フェイズ終了時なので+1は無しということでしょうか? お空の「巨星墜つ」に「制御棒」を配置した場合「巨星墜つ」の効果でダメージを受けるのは 戦闘フェイズ開始時なのでそのダメージは+1されない、で合ってますか? A:効果によるダメージは「特殊能力によるダメージ」なのでそもそも増えません。
https://w.atwiki.jp/medadictionary/pages/1905.html
対地制御 登場 7 DUAL 8 9 GM S 対地制御 技概要 技説明メダロット7 メダロットDUAL、ガールズミッション メダロット8 メダロット9 メダロットS 関連行動・技 技概要 メダロット7にて初登場した行動で、脚部パーツの地形相性を良くする効果を持つ。 行動名は3〜naviにかけて存在した重力制御を連想させ、実際に過去作で重力制御だったパーツは全てコレに置き換えられているが、仕様は大きく異なる。 ゲームバランスを考慮したためか、全ての登場作品で共通して頭部パーツやメダチェンジ後のドライブにしか存在しない。 技説明 メダロット7 メダロット7では地形によって脚部パーツのパラメータが上下に変動するが 対地制御を行うと一定時間全ての地形に影響されずにその恩恵を最大値で受けられるようになる。 その際、脚部タイプが「じゅうりょくC」に変化する。 効果中は何故かアンチエアの特攻が発動するので相手がアンチエアを持っているときは控えよう。 ちなみにメダリアの対地制御だとアンチエアの特攻は発動しない。 メダロットDUAL、ガールズミッション 全ての地形が得意になる効果をチーム全体に与えることが出来る。 メダロット8 仕様はほぼ7同様。 脚部タイプが変化する関係上エアーロボトル・マリンロボトルで使用すると全機が即死する羽目になる。 メダロット9 メダロット9では細かな仕様が変更された。 まず、脚部タイプは変化しなくなり、それに伴ってアンチエア特攻を受けなくなった。 メダロット9では、エアーロボトルとマリンロボトルで使用した際にも機能停止しなくなった また、ヘヴィリミットが最大値の3になるという特性も獲得。 コレによって博打や浪漫要素になる恐れこそあるが、ヘヴィリミットの低い脚部にヘヴィパーツを過積載するという戦術が出来る様になった。 メダロットS 基本的な仕様はメダロット9と同一。 脚部パーツの地形相性S以外の地形相性をAへと引き上げる。 このため、相性の揃いにくい戦車・車両向きといえる。 マイナス症状ゼログラビティとは、互いにその効果を打ち消すことが出来る相克(相剋とも)の関係にある。 基本的に頭部パーツの技のため多用はしづらいが、覚えておくと役に立つだろう。 頭部パーツにしか存在しないとはいえ、相性不利だが強力パーツや、ロボトルに有利な脚部特性を持ったパーツを使用するため、コレを持ち出すメダロッターも存在する。 なお、コレはメダロットSのみの仕様かもしれないが、脚部パーツを破壊されても、ヘヴィリミットが0として処理されなくなる。 リミットオーバーを狙って、脚部を優先するパワー・ハンター性格のメダルを使った集中攻撃、いわゆる脚刈り戦術への対抗馬となる。 関連行動・技 似て非なる効果を持つ行動 重力制御 頭と両腕に効果アリ、重力に魂を引かせない! 対地制御を含む複合技 ドミニオン 電脳の聖騎士による戦場支配
https://w.atwiki.jp/rubyiw/pages/34.html
5.制御構造 プログラムというものは、最初から最後まで、順番にコードが実行されるだけでは、さっぱり何の役にも立たないのである。とまあ、そこまで言い切ってしまうとあれだが、とてもではないが複雑な処理をすることはできない。ある条件に従って実行する行を変更したり、必要回数同じ処理を繰り返すためにくるくる回ったり、どこか別の場所にあるルーチンの内容を実行したりすることが必要なのだ。 エドガー・ダイクストラというオランダの情報工学者がいた。この学者先生は、ことプログラミングを勉強した人々の間では、非常に有名なのだ。『構造化プログラミング』という概念の提唱者なのである。 『構造化プログラミング』とは、年々大規模複雑化するシステム開発を円滑に進める方法論として、1967年に提唱されたものなのである。既に40年以上の歳月が流れているのだが、現在ただ今でも現役バリバリの理論であり、従来よりのプログラミングの概念を打ち破る革命的な手法が登場しない限り、まあこれ以外にないでしょうというものなのである。 『構造化プログラミング』の概念を実装できるプログラミング言語群は、『構造化プログラミング言語』と呼ばれており、Rubyなどの『オブジェクト指向プログラミング言語』よりほと世代前とされているわけだが、実際のところ、オブジェクト指向プログラミング言語で登場する『クラス』や『オブジェクト』は、その中に構造化されたプログラムロジックを内包、隠蔽しているだけと考えることができる。極論を言うと。 オブジェクト指向プログラミング言語を使用して開発する末端のプログラマこそ、オブジェクト間のメッセージのやり取りだけでアプリケーションを構築できるかもしれないが、クラス設計/実装者は、ダイクストラの提唱した『構造化プログラミング』の概念でもって中身を詰めているのである。 『構造化プログラミング』とは、プログラムをお互いに依存することなく、かつ不変契約(同じ値を渡せば常に同じ結果となることが約束されている)ちいさな部品(モジュール)を組み合わせて構築するという考え方である。さらに、そのモジュール内部は、構造化定理にのっとって記述されていなければならないとしている。 構造化定理とは、『全てのプログラムは、一つの入口と出口を持つ形(適正プログラム)に等価変形可能であり、適正プログラムでは任意のアルゴリズムを次の三つの基本的な制御構造で記述できる。その基本的な制御構造とは、順次(Seqence)、選択(Selection)、反復(Iteration)である』ということである。 Rubyにも、この三つの制御構造を実現するための命令(コマンド)が用意されているのである。 といっても『順次』構造は、命令が記述された順番に整然と実行されるということなので、とりたてて制御命令は存在しないのだが。 強いて言えば、『Rubyでは、特に明示的に実行順を入れ替えたり分岐させたりする制御命令を記述しなければ、なんと、書いた順番で処理しますよ。すごいでしょ』という言語仕様であろうか。まあ、そんなこと当たり前なのだが。 (1).選択(Selection) 『分岐』と表現している場合もある。ある条件があって、それが成立する場合(真の場合)と、成立しない場合(偽の場合)で、異なる処理を行うのが『選択』である。 Rubyには、選択構造を実現する命令として、次のものが準備されている。 if制御命令 if修飾子 unless制御命令 unless修飾子 case制御命令 (i)if制御命令 if制御命令は、プログラミング言語と名がつけば普通あるだろというほどメジャーなものだ。日本語で表現すると、『もし(if)、なになにがどうならば、これをせよ。でなければ(else)、あれをせよ。おしまい』となる。 だが、プログラミング言語によって書式が微妙に違い、同時期に複数の言語でプログラムを作っていたりすると、わけがわからなくなるときもある。Rubyでの書式は次の通りである。 if 条件式1 then 条件式が真の場合の処理(ステートメント) elsif 条件式2 then 条件式2が真の場合の処理(ステートメント) else 条件式2が偽の場合の処理(ステートメント) end 勿論、偽の場合を省略したいこともあるから、else以降は省略することができる。ただし、『おしまい』にあたるendは省略することができない。構文解析エラーとなってしまう。 厄介なことに、他のプログラミング言語には、この『おしまい』の合図を省略できるものが多いから、Ruby以外の言語をお使いの方は、ついうっかり忘れてしまうことがあるので気をつけよう。 なぜRubyでは endを省略できないのか。それは、『処理ブロックを明確にする』という目的というか、Rubyの設計哲学がある。ここで、プログラミング言語界の古株にして最強の武闘派であるC言語に登場してもらおう。 if ( a 10 ) b=1; else c=1; 仮に、上記のようなif文があったとしよう。このプログラムにある日仕様変更が入り、a 10の条件式が成立しなかった場合、変数dにも1を設定して欲しいということになったのだ。 神様であるお客様の意向には逆らえないので、プログラマ君はしぶしぶプログラムを書き換えたのである。 if ( a 10 ) b=1; else c=1; d=1; C言語をご存知の方であれば、このコードのアホさ加減はお分かりだと思う。 このコードは全くプログラマ君の意図した動きはせず、a 10の条件式が成立しようがしまいが、d=1の代入式が実行されてしまうのである。なぜならd=1の式は、if文の処理ブロック外にあるからなのである。 C言語の場合、if文の中で実行されるステートメントが1個だけの場合、処理ブロック指定を省略できるのだ。従って2個以上のステートメントを処理したければ、次のように、明示的に{}(中括弧)でブロックを指定してやらなければならない。 if ( a 10 ) b=1; else { c=1; d=1; } C言語では、改行コードに意味はないから、次のように記述してもなんら変わらない。 if ( a 10 ) b=1; else { c=1; d=1; } 次に、異形の怪物言語 VisualBasicを見てみよう。これがまた独特のルールに則っている。さすがは異形の怪物言語だけのことはあるのだ。 if ( a 10 ) b=1; else c=1; d=1; 上記のコードをVisualBasicで書き換えると次のようになる。 If a 10 Then b = 1 Else c = 1 d = 1 実はこのコード、なんとプログラマ君の意図した通りに動いてくれるのである。a 10の条件式が成立しなかった場合にのみ、ちゃんとd=1の代入が実行されるのだ。 一体どういうルールに則って動いているんだVisualBasicよ。と言いたくなるではないか。 VisualBasicの場合『同一行に記述されていれば、処理ブロックとしてみなしてあげます』というルールがあるのだ。VisualBasicの場合、改行コードというのが非常に重要な役割を持っているのである。ためしに、C言語のように行をわけて記述しようとすると、いきなり構文エラーになる。 If a 10 Then b = 1 Else c = 1 d = 1 エラー If の終わりには、対応する End If を 指定しなければなりません VisualBasicでは、if制御文が複数行に渡るときだけ、『おしまい』の合図、End Ifを指定しなければならないというわけだ。 このように、他の言語においてif制御構文は、よく言えばフレキシブル、悪く言えばよくわからない状態となっているので、Rubyにおいては、『たとえステートメントが1個であろうが、ちゃんとendを記述して、処理ブロックを明確にしようじゃないか』というルールを定めているのである。 なお、これも、他の言語の経験がある方に注意していただきたいのが、elseの場合に、また条件式を指定したい場合だ。 Rubyの場合、elsifという独特な記述方法になる。 elseif でも else if でもないから注意しよう。このelsifという書式は、スクリプト言語の偉大なる先達、Perlと同じだということを参考までに付記しておく。 さて、Rubyのif制御文には、他のプログラミング言語では見かけない特色がある。それは、『if制御文自身が値を保持する』ということなのである。 代入式が値を持つプログラミング言語はあちらこちらで散見されるものの、if制御文自体が値を保持するプログラム言語は少ないのだ。 a = if b 10 then true else false end 『あれ?なあんだ。三項演算子と同じじゃないですか』 まあそうなのだが。 (ii)if修飾子 if制御命令は、プログラミング言語と名がつけば、普通あって当たり前なのだが、このif修飾子については、存在する言語は少ない。先達のPerlがこのif修飾子を持っているので、Perlから強く影響を受けているRubyにもあると言ってもいいかもしれない。 if修飾子は、次のように記述する。 puts "aは10より小さい" if a 10 コードを眺めていれば、自然と納得がいくかと思うが、要するに、”aは10より小さい”という文字列を出力したいわけだが、それを実行するにあたって、コードの後ろに条件式を指定することができるのである。この場合、if a 10 がその条件になる。irbで動作を確認してみよう。 この判定は、普通にif制御命令を使用して記述することもできるのだが、なんとなく回りくどい感じがする。if修飾子は面倒くさがりのプログラマへのRubyからのささやかなプレゼントと言えよう。 (iii)unless制御命令 unlessは、ifの逆である。ifは、条件文が真となったときにステートメントが実行されるが、unlessは偽となったときに実行される。 プログラミングの経験がある皆さんには、なにやら複雑な複合条件でif文を構築して、なんとなく動いたと思ったら、『悪りぃ。あそこの条件だけどさ。逆にしてくんない』といわれ、もうわけがわからん!とやけを起こして、次のような記述にしてしまったことはないだろうか。 (オリジナル) if ( a =4 || b 1 ) ( c 5 c 10 ) then 処理 end (修正後) if ( a =4 || b 1 ) ( c 5 c 10 ) then #何もしない else 処理 end これはちょっと不細工な気がする。明らかに考えることを放棄しているのがバレバレだ。そういうときにunlessを使用すると、少しは体裁がよくなる。 unless ( a =4 || b 1 ) ( c 5 c 10 ) then 処理 end まあ、条件式を組み立てなおさないという意味では同じなのだが。 unless制御命令にもelseを書くことができる。この場合、else以下は条件式が真の時に実行されることになる。ただし残念ながら、elsifは指定できないし、elunlessなどという記法はない。『もしかしてあるかもね?』と期待された方には申し訳ないが。 (iv)unless修飾子 unless修飾子は、if修飾子と逆の動きをする。 puts "aは10以上である" unless a 10 unlessが存在することにより、条件式の組み立てが非常に楽になるのだが、残念ながらC、C++言語、C#といった中大規模システム構築用のコンパイラ系言語には準備されていない。それらの言語でややこしい条件式を組み立てているときに、ふと『unlessがあればなあ』と思うことがよくあるのだが。 (v).case制御命令 if制御文は、ある条件式があって、それが真か偽かの二者択一であったが、世の中そうなにごとも、真偽で判定できるものではなく、三通り以上の選択肢があることが多いのだ。その場合に重宝するのがこのcase制御命令なのである。 case month when 2 puts "二月は特別です" when 4,6,9,11 puts "西向くさむらい小の月です" else puts "大の月です" end 上記は、変数monthの値が、2の場合、4か6か9か11の場合、そして、それ以外の場合で出力するメッセージを切り替えている例だ。 この場合、たまたま評価されるものが変数となっているが、当然演算式でも、代入式でも、比較演算式でも構わない。 when節にある値の指定は、演算子のところででてきた、範囲演算子が指定できる。 case ji when 6..11 puts "おはようございます" when 12..18 puts "こんにちは" else puts "こんばんは" end それぞれ、6から11、12から18の範囲を持つということになるわけだ。 さらに、case に続く式を省略することもできる。この場合、 when節が順に評価されていき、最初に真となった式が評価される。 case when (6..11) === ji puts "おはようございます" when (12..18) === ji puts "こんにちは" else puts "こんばんは" end 以上で『選択』の解説は終了だ。 ん?『さらっと流さないでください。===(イコールみっつ)ってなんですか?そんな演算子、解説してないじゃないですか』 実はこの===演算子、普遍的な演算子ではない。Rangeオブジェクトだけに定義されている特別な演算子なのだ。 これを『クラスにおける演算子の多重定義(オーバーローディング)』と呼ぶのだが、詳細はクラスの解説をするときに併せて説明しよう。===は、右辺の値が、左辺のRangeオブジェクトが持つ範囲にあれば真、なければ偽になるという便利な演算子というわけなのであった。 (2).反復(Iteration) 反復を実現する制御命令には、次のものがある。 while 制御命令 while 修飾子 until 制御命令 until 修飾子 for 制御命令 (i)while制御命令 while制御命令の書式は以下の通りだ。 while 式 [do] ... end whileは、条件式が真である間、endまでに記述されたステートメントを繰り返し実行する。 whileの条件式は、可能な限りいつか偽となることが保証されるものが望ましい。さもないと、忌むべき永久ループという状態に陥ってしまう。 例として、Rubyリファレンスマニュアルに記載されているサンプルコードを見てみよう。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | i = 0 003 | while i ary.length 004 | print ary[i] 005 | i += 1 006 | end これは、配列aryの要素を順番に出力していくものだ。条件式は i ary.lengh だから、変数iが、配列aryの要素数より小さい間は真になる。そしてこの条件式が偽になるのはいつかというと、5行目のi += 1で、変数iの値がiづつカウントアップされている。ここでいつかはiの値が配列aryの要素数と同じになるときがくるのだ。そのとき、めでたくこの条件式が偽となるのである。 なぜiが配列aryの要素数とイコールになるまでではなく、-1までかというと、変数iがそのまま配列aryの要素番号になっているからだ。 配列の要素番号は 0から要素数-1までであるから。これは、あまたのプログラミング言語仕様においては、最も基礎的なことだ。 さて、このようなコード記述したときに、うっかり忘れてしまいがちなのが、5行目のカウントアップ処理なのである。これがないと、このwhile文は、永久にループしてしまうのだ。であるから、配列の要素数分処理をしたい場合は、イテレータ、すなわち配列オブジェクトが持つeachメソッドを使用するほうが無難だし、簡単だ。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | ary.each { |i| 003 | print i 004 | } (ii)while修飾子 while にもifやunlessと同様に、修飾子としての書式が存在する。ステートメントの実行にあたって条件があるので、修飾子が存在するのが普通と考えるべきだ。 前出のコードを修飾子を使って書き換えると次のようになる。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | i = 0 003 | begin 004 | print ary[i] 005 | i += 1 006 | end while i ary.length なんだ、余計に記述量が増えているではないか。このコードの場合、whileで実行されるステートメントが複数あるから、 begin~endで処理ブロックを作る必要がある。whileで実行するステートメントがひとつである場合に限り、whileに対するendを省略できるから、若干記述量の節約になるのであった。 (iii)until制御命令 while制御命令は、条件式が真である間、処理を実行するものであったが、until制御命令はその逆、即ち条件が真になる間、言い換えれば、条件が偽である間処理を実行するものである。 until 式 [do] ... end 前出のwhileのコードをuntilで書き換えると次のようになる。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | i = 0 003 | until i =ary.length 004 | print ary[i] 005 | i += 1 006 | end (iv)until修飾子 whileにも修飾子としての記述法があるので、当然このuntilにも修飾子としての記述法が存在する。条件が『~の間』と『~になる迄』という相違だけで、この二つの制御構造は一卵性双生児といえるのである。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | i = 0 003 | begin 004 | print ary[i] 005 | i += 1 006 | end until i =ary.length while制御構造とuntil制御構造、そしてwhile修飾子とuntil修飾子。先ほど評したように双生児ではなく、こりゃはっきり言って四つ子のようなこれらの命令群をどのような局面で使い分けたらよいのであろうか。 それは、最終的に個人の好みに帰結するのである。 (v)for制御命令 while制御命令、until制御命令とも、実は他のプログラミング言語にも普通に存在し、かつ同様な書式で、同様な動きをするので、ほっと一安心されたかと思う。 その流れから判断すれば、 for制御命令だって他のと同じようなものだろうと甘く見るとノツボにはまるので注意が必要だ。 Rubyのfor制御文は、他の言語とは一味違うのである。 もし皆さんが他のプログラミング言語をご存知であればあれば、 for制御文というと、次のようなものを想起されると思う。 【C、C++、C#、Java】 int i; for ( i=0; i 10; i++ ) { ... } 【Visual Basic】 Dim i as Integer For i=0 To 9 ... next 【pascal】 var i Integer; begin for i =0 to 9 do begin ... end; end; Rubyと関係ないことをだらだら書いて、行を無駄遣いしやがってこの野郎とのご批判もあろうが、要するに、『凡百(?)のプログラミング言語では軒並み、 for文とは、ある変数(カウンタ)があって、それがある決まった値になるまで、増加(または減少)している間、ステートメントが実行されるのだぞ』ということを強調したいのである。 で、最終的に、『ところがどっこいRubyの For文はちょっと違うぞ』ということが言いたいのだ。 Rubyにおいて、for制御命令の書式は次の通りだ。 for 変数 ... in 式 [do] ... end 【in 式】の式の部分には、以前解説させていただいた『範囲オブジェクト』、または『配列オブジェクト』が指定されるのだ。結果的に『範囲オブジェクト』または、『配列オブジェクト』であればよいわけだから、関数の戻り値でも、クラスメソッドの戻り値でも、値を保持するステートメントでもよいのである。 他のプログラミング言語で例示したコードをRubyの for制御命令で書き換えると、次のようになる。 for i in 0..9 ... end あれ。これも前回の最後に出てきた配列または範囲オブジェクトのeachメソッドで処理してもいいのでは?と思われた方も多数いらっしゃると思う。なにを隠そうそれは正解だ。 実際に、eachメソッドで処理してもなんら問題ないのである。 (0..9).each { |i| ... } ところが、 for制御命令とeachメソッドの呼び出しには、決定的な違いがひとつだけ存在するのだ。Rubyのリファレンスマニュアルには、次のように記してある。 『 do ... endまたは{ }によるブロックは新しいローカル変数の有効範囲を導入するのに対し、 for文はローカル変数のスコープに影響を及ぼさない点が異なるからです』 一読して何のことやらよくわからないかもしれないので、例示して説明しよう。次のコードを見ていただきたい。あまり素敵な例とは言えないのだが。 001 | j=10 002 | for i in 1..10 003 | if i==1 then k=10 end 004 | puts (i+j).to_s 005 | k+= (i+j) 006 | end 007 | puts k.to_s forループの中で、kという変数が突然誕生しているのがわかると思う(3行目)。その変数kをforループの外側で参照しているのである。 このコードは、無事正常終了する。では同じことをeachメソッドでやってみる。 001 | j=10 002 | (1..10).each { |i| 003 | if i==1 then k=10 end 004 | puts (i+j).to_s 005 | k+= (i+j) 006 | } 007 | puts k.to_s 残念なことに、これは正常に実行できず、エラーとなってしまうのだ。 【NameError undefined local variable or method `k for main Object】 7行目の変数kなどというものは知らんと怒っているのである。 なぜそのようにRubyが怒るのかというと、変数 kは、each文の{}(中括弧)で閉ざされた内部だけで有効なローカル変数であり、eachの外部からは見えないのだ。要するにスコープが違うのである。 しかし、For文の中であれば、外部と同じスコープであるというわけなのだ。 さて、 for制御命令でも、配列のeachメソッドでもループ処理ができて嬉しいなと喜んでいたところ、なんとRubyには、まだ別の方法が存在する。 サンプルコードの場合、くるくる回る回数は10回であるということがあらかじめわかっている。であれば、次のような記述も可能なのである。 001 | j=10 002 | k=0 003 | 10.times{ |i| 004 | puts (i+1+j).to_s 005 | k += (i+1+j) 006 | } 007 | puts k.to_s 数値オブジェクトの timesメソッドを使用する方法だ。ループ処理ひとつをとってもこれだけたくさんの書法が存在するのである。一体どれを使えばいいのだと悩ましいところであるが、結論から言うと先ほど申し上げたように、最後は実装者個々の好みということになる。 さて、これで反復を実現する制御命令について解説し終わったわけだが、補足として、反復用制御命令と関連して動作する制御命令を解説しておく。 (vi)break break は、反復処理制御を開始するときに定められた終了条件を満たす以前に、反復処理を抜け出したいときに使用する。反復処理とは、以下のものを指すということは、既にみなさんお分かりだと思う。 while until for イテレータ コード例を挙げておこう。 001 | ary = [0,2,4,8,16,32,64,128,256,512,1024] 002 | i = 0 003 | while i ary.length 004 | unless DoSomeThing(ary[i]) then 005 | break 006 | end 007 | print ary[i] 008 | i += 1 009 | end さてここで、もし貴方がC系のプログラミング言語経験者である場合、ひとつ疑問に思ってほしいことがあるのだ。 それは『case制御命令において、breakは必要ないのか?』ということだ。 C言語において、Rubyのcase制御命令に該当するswitch制御命令の構文は次の通りだ。 001 | switch ( month ) 002 | { 003 | case 2 004 | printf "二月は特別です\n"; 005 | break; 006 | case 4 007 | case 6 008 | case 9 009 | case 11 010 | printf "西向くさむらい小の月です\n"; 011 | break; 012 | default 013 | printf "大の月です\n"; 014 | } このように、 C言語系のswitch制御構文においては、各case節に記述されるステートメントの最後は、breakであることが望ましい。なぜなら、breakを指定しておかないと、下までずるずるっと実行されてしまうからである。 上記のコードで、5行目のbreakを忘れると、変数monthの値が2であった場合、 6行目から10行目までが一気に実行されてしまい、11行目の breakでやっと止まるということになってしまうのである。 変数monthの値が4でも6でも9でも11でもないに関わらずだ。 『なぜそんな変な仕様になっているのですか?』 知らん。 幸いなことにRubyでは、このcaseのずるずる流れ込みが存在しない。 変数の値が2であれば、2の場合に実行するよう記述したステートメントしか実行されないことが保証されている。従ってcase制御構文に breakは必要ないというわけである。 (vii)next nextは、 for制御構文内、または、イテレータの処理内において、ある条件であれば処理をスキップしたいときに使用する。 001 | #for制御構文の場合 002 | for i in 1..10 003 | next if i==5 004 | puts i.to_s 005 | end 006 | 007 | #イテレータの場合 008 | (1..10).each { |i| 009 | next if i==5 010 | puts i.to_s 011 | } 上記二つのコードは、どちらもiの値が5の場合、処理をスキップする。念のため、irbで動作を確認しておこう。5の表示がすっ飛ばされていることを確認していただきたい。 (viii)redo redoも、 for制御構文内、または、イテレータの処理内において使用する。ある条件が成立すれば、ループ条件のチェックを行わず、現在の処理を繰り返すものである。 001 | #for制御構文の場合 002 | for i in 1..10 003 | puts i.to_s 004 | redo if i==5 005 | end 006 | 007 | #イテレータの場合 008 | j=10 009 | k=0 010 | (1..10).each { |i| 011 | puts i.to_s 012 | redo if i==5 013 | } 上記二つのコードは、どちらもiの値が5の場合、処理を繰り返す。ご想像の通り、これらコードは、1から5の数字を画面表示した後、そのままループして永遠に5を表示し続けるのだ。実際には、こんなコード書いてはいけないし、実行してもいけない。 (ix)retry retryも、for制御構文内、または、イテレータの処理内において使用するものだ。 retryは、ある条件が成立すれば、なんとご苦労なことに、ループ処理の最初からもう一度やり直のである。。 001 | #for制御構文の場合 002 | for i in 1..10 003 | puts i.to_s 004 | retry if i==5 005 | end 006 | 007 | #イテレータの場合 008 | j=10 009 | k=0 010 | (1..10).each { |i| 011 | puts i.to_s 012 | retry if i==5 013 | } 上記二つのコードは、どちらもiの値が5の場合、ループの最初に状態を戻す。ご想像の通り、これらのコードは、1から5までの表示を永遠に繰り返すのである。くどいようだが、実際にはこんなコード書いちゃいけないからね。