Ruby

出典: フリー百科事典『ウィキペディア(Wikipedia)』
Ruby
Rubyのロゴ
パラダイム 関数型プログラミング命令型プログラミングオブジェクト指向プログラミングリフレクション ウィキデータを編集
登場時期 1995年 (28年前) (1995)
開発者 まつもとゆきひろ ウィキデータを編集
最新リリース 3.2.2 - 2023年3月30日 (6か月前) (2023-03-30)[1] [±]
型付け 強い動的型付け, ダック・タイピング
主な処理系 MRI, YARV, JRuby, IronRuby, MacRuby
影響を受けた言語 AdaDylanPerlPythonSmalltalkC++CLUEiffelLISPBASICLuaEmacs ウィキデータを編集
影響を与えた言語 D言語[2]GroovySwiftCrystalScalaElixir
プラットフォーム Microsoft WindowsGNU/Linux、BSD、macOS ウィキデータを編集
ライセンス Rubyライセンス、GPL 2.0、2条項BSDライセンス ウィキデータを編集
ウェブサイト www.ruby-lang.org ウィキデータを編集
拡張子 rb、rbw ウィキデータを編集
テンプレートを表示

Ruby(ルビー)は、まつもとゆきひろ(通称: Matz)により開発されたオブジェクト指向スクリプト言語(スクリプト言語とはプログラミング言語の一分類)。

日本で開発されたプログラミング言語としては初めて国際電気標準会議(IEC)で国際規格に認証された事例となった[3]

概要[編集]

Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearl(真珠)と同じ発音をし、「Perlに続く」という意味で、6月の次の誕生石(7月)のルビーから名付けられた[4]。競合言語として Perl の他に Python があり、「Matz(まつもと) が Python に満足していれば Ruby は生まれなかったであろう」と公式のリファレンスの用語集で言及されている[4]

機能として、クラス定義ガベージコレクション、強力な正規表現処理、マルチスレッド例外処理イテレータクロージャMixin利用者定義演算子などがある。Perl を代替可能であることが初期の段階から重視されている。Perlと同様にグルー言語としての使い方が可能で、C言語プログラムやライブラリを呼び出す拡張モジュールを組み込むことができる。

Ruby 処理系は、インタプリタコンパイラが存在する(詳しくは#実装を参照)。

可読性を重視した構文となっている。Ruby においては整数や文字列なども含めデータ型はすべてがオブジェクトであり、純粋なオブジェクト指向言語といえる。

長らく言語仕様が明文化されず、まつもとによる実装が言語仕様に準ずるものとして扱われて来たが、2010年6月現在、JRuby や Rubinius といった互換実装の作者を中心に機械実行可能な形で明文化する RubySpec という試みが行われている。公的規格としては2011年3月22日にJIS規格(JIS X 3017)が制定され、その後2012年4月1日に日本発のプログラム言語では初めてISO/IEC規格(ISO/IEC 30170)として承認された [3]

フリーソフトウェアとしてバージョン1.9.2までは Rubyライセンス(Ruby License や Ruby'sと表記されることもある。GPLArtisticに似た独自ライセンスを選択するデュアルライセンス)で配布されていたが、バージョン1.9.3以降は2-clause BSDLとのデュアルライセンスで配布されている[5]

ゆかりのある地域[編集]

Rubyは日本の国産言語として知られており、特にRubyとゆかりのある地域はRubyの聖地と呼ばれている。

設計思想[編集]

開発者のまつもとゆきひろは、「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミングを楽しむことである (enjoy programming)」と述べている。

Ruby には Perl や Python とは決定的に違う点があり、それこそが Ruby の存在価値なのです。それは「楽しさ」です。私の知る限り、Ruby ほど「楽しさ」について焦点を当てている言語は他にありません。Ruby は純粋に楽しみのために設計され、言語を作る人、使う人、学ぶ人すべてが楽しめることを目的としています。しかし、ただ単に楽しいだけではありません。Ruby は実用性も十分です。実用性がなければ楽しめないではありませんか。 — まつもとゆきひろ、Ruby プログラミング入門 まえがき 監修者よりのページ

ただし、まつもとによる明文化された言語仕様は存在しない。Perlのモットー「やり方はいろいろある (There's More Than One Way To Do It; TMTOWTDI)」は「多様性は善 (Diversity is Good)」というスローガンで Ruby に引き継がれてはいるものの最重要なものではないとも述べており、非推奨な手法も可能にするとともに、そのような手法を言語仕様により使いにくくすることによって自粛を促している。

また、まつもとは『まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法』でもRubyの開発理由を次のように述べている。

「なぜRubyを開発したのか」。そのように問われるときに、もっとも適切な答えは、Linux開発者であるリーナス・トーバルズの言葉と同じではないかと思います。『それがぼくには楽しかったから — まつもとゆきひろ、まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法 P.9

また、英語圏の開発者の間ではMINASWAN (Matz is nice and so we are nice. 和訳: まつもとがナイスだから我々もナイスであろう) の標語が用いられている。

「Python、PHP、Perlでは静的型を導入しているため、Rubyも型を導入するべきでは」と長年言われているが、まつもとは「Rubyに型を取り入れたくない。DRY (Don't repeat yourself)ではないから⁠」⁠「⁠型宣言することはコンピュータに使われているような気になる」と否定的であり、2019年5月現在Rubyに静的型が導入される予定はない[7]

クラス名はアルファベットの大文字から始めるという制約があり、日本語などの非ASCII文字のみでクラス名を定義する方法がない。この件についてまつもとは以下のように語っており、英語を共通言語として使うべきであるという立場を表明している。

2文字目以降は自由なので、もしどうしても日本語が使いたいのであれば、少々不自然にも見えますが、先頭だけ大文字の接頭辞をつけるのはどうでしょうか。しかし、私個人としては、日本語の変数名などを使うことは、そのプログラムを読む人の範囲を日本語が読める人に限定してしまうことになるので、ひどくもったいないのではないかと感じています。そこで、この点を積極的に改善する気にはなれないのです。[8]

実装[編集]

公式な実装[編集]

Rubyの公式な実装には、以下の二種類が存在する。

MRI(Matz' Ruby Implementation)
まつもとゆきひろによって開発されはじめたC言語による実装であり、最も広く使われている。狭義として、evalを中心とした部分が次で述べるYARVに更新される以前(1.8.x以前)のバージョンを指して言うこともある。JRuby などに対して CRuby と呼ばれることもある。また、JRuby などに対して、広義として YARV 以降も含んで言うこともある。
YARV
1.9で採用された、MRIのevalをバイトコードを実行するタイプに置き換えたもの。(狭義の)MRIはソースコードを構文木にコンパイルした後、構文木を解釈する仮想機械であるevalで実行するインタプリタであるが、YARVはソースコードをバイトコードにコンパイルした後、バイトコードを解釈する仮想機械であるevalで実行するインタプリタである。Javaなどのバイトコードとは違い、このバイトコードはファイルとしては生成されない(ファイルとして静的に外部化することを考慮した設計では基本的になく、シンボルを多用するなどしている)。なお「YARV」は、もともとは開発中におけるその仮想機械の名前だった。

その他の実装[編集]

JRuby
Java 言語による実装。純粋な Java で行われているため、プラットフォーム非依存の利用が可能。ほとんどの Ruby クラスが組み込みで提供されている。インタープリタ・実行時コンパイラ事前コンパイラの3種類が用意されている。事前コンパイラでは、Java バイトコードへ変換し、JRuby が無くても他の Java プラットフォーム上で動作させることが可能となる。
IronRuby
.NET Framework 上で Ruby を動作させる実装であり、.NET Framework のライブラリと連携させることができる。JIT方式のバイトコードインタプリタ。共通言語基盤に準拠した実装(Monoなど)で動作するため、プラットフォーム非依存の利用も可能(ただし、ソースコードが .NET Framework のライブラリに依存している場合は Mono での動作は不可能)。
MacRuby英語版
macOS 上で動作する Ruby 実装。Cocoa を含む様々なフレームワークとの連携が可能。RubyCocoa の問題点を解決するために開発されている。
Rubinius英語版
仮想機械上で Ruby を実行するJIT方式のバイトコードインタプリタ。大部分が Ruby で実装されている。
MagLev英語版
smalltalk仮想マシン上で動作する実装 MagLev
mruby
組み込みシステム向けの軽量版。家電製品の他、スマートフォンゲームなどでの使用を想定している。
その他
Parrot 上で Ruby を動作させるための実装なども開発されている。

[編集]

基本的なコード

# 文字列、数値を含め、全てがオブジェクトである
-199.abs                                       # 199
"ruby is cool".length                          # 12
"Rick".index("c")                              # 2
"Nice Day Isn't It?".split(//).uniq.sort.join  # " '?DINaceinsty"

コレクション[編集]

配列の作成と使用法

a = [1, 'hi', 3.14, 1, 2, [4, 5]]

a[2]                      # 3.14
a.reverse                 # [[4, 5], 2, 1, 3.14, 'hi', 1]
a.flatten.uniq            # [1, 'hi', 3.14, 2, 4, 5]

ハッシュの作成と使用法

hash = {'water' => 'wet', 'fire' => 'hot'}
hash = {water: 'wet', fire: 'hot'} # シンボルリテラルをキーとする場合、Ruby 1.9 からはこのような Javascript 風の表記ができる。
puts hash[:fire]       # 表示:  hot

hash.each do |key, value|
  puts "#{key} is #{value}"
end

# 表示:               water is wet
#                     fire is hot

hash.delete_if {|key, value| key == :water}   # Deletes :water => 'wet'

制御構造[編集]

ほかの言語でもよくみられるような制御構造を用いることができる。

if "fablic".length > 3
  puts 'ya'
else
  puts 'nop'
end
# 表示:         ya

list = [1, 2, 5, 13, 21]
for item in list
  puts item
end
# 表示:         1
#               2
#               5
#               13
#               21

n = 0
while n < 3
  puts 'foobar'
  n += 1
end
# 表示:         foobar
#               foobar
#               foobar

上記、

if "fablic".length > 3
  puts 'ya'
else
  puts 'nop'
end

については、

puts "fablic".length > 3 ? 'ya' : 'nop'

または、

puts(
  if "fablic".length > 3
    'ya'
  else
    'nop'
  end
)

のような記述もできる。

一部の制御構造は後述するイテレータで代替することができる。

ブロック付きメソッド呼び出し[編集]

Ruby ではブロック付きメソッド呼び出しを用いるコードが好まれることが多い。これを用いると、ユーザー定義の制御構造コールバックなど様々な処理を簡潔に記述できるからである。

ブロックとは波括弧 {} または doend によって囲まれたコード列のことである。メソッド呼び出しの末尾に記述することが出来る。この2つは基本的に同一だが、結合の優先度が異なる。慣習的に一行で書くときは波括弧が、複数行に渡る場合はdoendが使用される場合が多い。

# { ... }
method1 { puts "Hello, World!" }
# do ... end
method2 do
  puts "Hello, world!"
end

ブロック付きメソッド呼び出しが繰り返し処理を主な役割としていたことから、イテレータと呼ばれていた時期がある。しかし、実際には繰り返し処理にとどまらず、様々な使われ方をしているので、最近はブロック付きメソッド呼び出し全体の総称としてイテレータという名称を用いるのは適切でないと考えられている[9]

繰り返し処理[編集]

配列の各要素への繰り返し処理

list = [1, 2, 5, 13, 21]
list.map! {|item| item * 2} # listの各要素を2倍する処理

以下はブロックを使わずに同じことを行う場合

list = [1, 2, 5, 13, 21]
n = 0
while n < list.length
  list[n] *= 2
  n += 1
end

指定した回数の繰り返し処理

3.times { puts 'foobar' }       # 制御構造の項のwhileの例と同じ

gsub()による文字列置換の繰り返し処理

puts "ABC-ABC".gsub("B", "1B2")        # OK "A1B2C-A1B2C"
puts "ABC-ABC".gsub(/(B)/, "1#{$1}2")  # NG "A12C-A12C"
puts "ABC-ABC".gsub(/(B)/){"1#{$1}2"}  # OK "A1B2C-A1B2C"

後処理の省力化[編集]

ブロックの内容を実行してから、決められた後処理を行うメソッドもある。

File.open('file.txt', 'w+b') do |file|
  file.puts 'Wrote some text.'
end                             # file.txtはここで自動的に閉じられる

これは次の例と同様の処理を行う(ensure については例外処理の項を参照)

begin
  file = File.open('file.txt', 'w+b')
  file.puts 'Wrote some text.'
ensure
  file.close
end

本処理を後から指定[編集]

実際に行いたい処理をブロックで記述する。前項の後処理の省力化もこれの一例といえる。

def bfs(list)       #配列をツリーに見立てた処理
  until list.empty?
    unit = list.shift
    yield unit      #ブロックの内容を実行
    unit.each{|v| list.push v} if defined? unit.push
  end
end
bfs([0,1,[2,3],4,[5,[6,7,8]],9]) {|v| p v}

この例は、ツリーから要素と分枝をつぎつぎと取り出して取り出したものになんらかの処理を行うものである。メソッドの利用者は、なんらかの処理のみを記述すればよく、取り出しのアルゴリズムなど、本質的でない内容に意識を向ける必要がなくなる。

クロージャ[編集]

クロージャとなるようなブロックの引数渡し

# オブジェクトのインスタンス変数(変数名の頭に@が付く)でブロックを記憶。
def remember(&p)
  @block = p
end
# nameを受け取るブロックを引数に、上記のメソッドを呼び出す。
remember {|name| puts "Hello, " + name + "!"}

# 後に必要になった時点でクロージャを呼び出す。
@block.call("John")
# 表示:"Hello, John!"

メソッドからクロージャを返す例

def create_set_and_get(value = 0)
  return proc {|x| value = x}, proc { value }
end

setter, getter = create_set_and_get
setter.call(21)
getter.call # => 21

クラス[編集]

次のコードはPersonという名前のクラスである。その中、まずinitializeはオブジェクトを初期化するコンストラクタである。ほかに2つのメソッドがあり、1つは比較演算子である<=>オーバーライドしておりArray#sortによりプロパティageでソートすることができる。もう1つのオーバーライド箇所のto_sメソッドは Kernel#puts での表示の形式を整える。attr_readerは Ruby におけるメタプログラミングの例であり、attr はインスタンス変数の入出力を司る、いわゆる値を取得する getter メソッドや値を設定する setter メソッド(アクセサ)を定義する。attr_readergetter メソッドのみの定義である。なおメソッド中では最後に評価された式が返り値となり、明示的なreturnは省略できる。

class Person
  def initialize(name, age)
    @name, @age = name, age
  end

  def <=>(person)
    @age <=> person.age
  end

  def to_s
    "#{@name} (#{@age})"
  end

  attr_reader :name, :age
end

group = [ Person.new("John", 20),
          Person.new("Markus", 63),
          Person.new("Ash", 16)
        ]

puts group.sort.reverse

結果は3つの名前が年の大きい順に表示される

Markus (63)
John (20)
Ash (16)

例外処理[編集]

例外はなにか不具合が起こったときraiseの呼び出しで発生させることができる。Ruby での例外は Exception クラスか、そのサブクラスのインスタンスである。

例外にはメッセージを追加することもできる

 raise "This is a message"

さらに例外のタイプも指定できる

 raise ArgumentError, "Illegal arguments!"

例外はrescue節で処理することができ、次のようにコードにrescueを付加するだけである

begin
  # 通常処理
rescue
  # 例外処理。引数を省略すると、StandardErrorのサブクラスの例外のみ処理する
rescue SomeError
  # 例外処理。SomeErrorの例外のみ処理する。
ensure
  # 例外の発生に関わらず必ず実行される処理
else
  # 例外が発生しなかったときに実行される処理
end

不向きな処理[編集]

ベンチマークテストで使用される以下のようなコードを実行したとき、著しい処理速度の低下を観察することがある。

i1 = 1000000
while i1 <= 1010000
	i2 = i1 - 1
	i3 = 2
	while i3 <= i1
		if (i1 % i3) == 0
			break
		elsif i3 == i2
			puts i1.to_s
			break
		end
		i3 += 1
	end
	i1 += 1
end

Rubyの周辺技術[編集]

Rubyで開発されたアプリケーション[編集]

Rubyを組み込んだアプリケーション[編集]

RPGツクールXP・RPGツクールVX
株式会社エンターブレインから発売されているRPG制作ソフトシリーズのうち、RPGツクールXPRPGツクールVXでは、Ruby をツクール専用にカスタマイズした RGSSを搭載している。同シリーズの従来ソフトではあらかじめ用意された機能しか使えなかったが、RGSSにより戦闘などのシステムを一から構築する事が出来るようになった。
RPGツクールMVからは開発言語がJavaScriptに変更になった。

エピソード[編集]

Ruby ではブロック構造を end で終える構文が採用されているが、開発者のまつもとゆきひろは他の構文が採用される可能性があったことを述べている。当時、Emacs 上で end で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためである[注釈 1]。実際には数日の試行でオートインデント可能であることがわかり、現在の構文になった。C言語のような{〜}を使った構文も検討されていたが、結局これは採用されなかった[11]

「Rubyは死んだ」[編集]

「Rubyはよく『死んだ』って言われる言語である」とまつもとは認識しておりTwitterRuby on RailsからJava仮想マシン用言語のScalaに移行した話などを例に出し「Rubyは死んだ」みたいに言われることが増えたとしているほか、オランダのTIOBEという会社が発表しているプログラミング言語の人気ランキングでRubyが上位に入らないことをもってして「Rubyは死んだ」「Rubyは凋落している」と見られることがあるが、「RubyとかRuby on Railsだと、さまざまなジャンルで実際の適用例があるので、なにか困ったとき同じ問題に直面した人を探せたり、あるいはその問題を解決するRubyGemsを見つけられる。そういう点でいうと、トータルの生産性はかなり高いことがある」「実際に仕事として、あるいは自分のプロダクトを作るときに、どんな言語を選択してどういうふうに開発したらいいのかを考えると、Rubyの持っているビジネス上の価値はそんなに下がっていないと思います。たとえ順位が下がって、表面上Rubyの人気が凋落したように見えても、ある意味『まだまだ大丈夫』が1つの見識だと思います」とまつもとは述べている[12]

Ruby on RailsがPythonで作られなかった理由[編集]

デイヴィッド・ハイネマイヤー・ハンソンがRuby on Railsを構築するのにPythonを選ばなかった理由として「私の場合は、恋に落ちたのがRubyなのです。私はRubyに恋をしていますし、もう14年間もそうなのです。(中略)『最適なツール』などというものは存在しないのです。あなたの脳をちょうどいい具合に刺激するパズルがあるだけなのです。今日では、ほぼなんでも作ることができます。そして、それを使って、さらに何でも作れてしまうのです。これは素晴らしいことです。表現や言語、そして思考の多様性に乾杯しましょう!」と質問サイトのQuoraで本人が回答している[13]

まつもとゆきひろが書いたコードの割合[編集]

2020年9月8日現在、RubyのCコード509,802行のうち、まつもとがコミットしたのは36,437行で1割以下になっている[14]

脚注[編集]

注釈[編集]

  1. ^ まつもとゆきひろは1988年に Emacs に触れて以来、Emacsを使い続けている[10]

出典[編集]

  1. ^ naruse (2023年3月30日). “Ruby 3.2.2 リリース”. ruby-lang.org. 2023年5月24日閲覧。
  2. ^ Intro - D Programming Language 1.0 - Digital Mars
  3. ^ a b プログラム言語Ruby、国際規格として承認』(プレスリリース)独立行政法人情報処理推進機構、2012年4月2日https://www.ipa.go.jp/about/press/20120402_2.html 
  4. ^ a b Ruby用語集(Ruby 2.7.0 リファレンスマニュアル)”. 2020年2月7日閲覧。
  5. ^ Ruby License”. ruby-lang.org. 2020年9月29日閲覧。
  6. ^ a b c Tech通信”. 2019年3月1日閲覧。
  7. ^ まつもとゆきひろさん「Ruby3の目指す未来 –The Year of Concurrency–」〜RubyKaigi 2019 1日目 基調講演:RubyKaigi 2019 Keynote レポート|gihyo.jp … 技術評論社
  8. ^ Rubyのクラスと定数の先頭をアルファベット大文字に限定しているのはなぜですか?クラス名を日本語にできないのが他の言語ではできるので少し惜しい気がします。”. Quora. 2022年6月11日閲覧。
  9. ^ [ruby-list:39878] Re: イテレータとfor文
  10. ^ 大竹智也「本書に寄せて」『Emacs実践入門 思考を直感的にコード化し、開発を加速する』(初版第1刷)技術評論社、2012年4月5日、iiiからivページ頁。ISBN 978-4-7741-5002-4 
  11. ^ まつもとゆきひろ 「探訪 Ruby 第6回」『Linux Magazine』56号、株式会社アスキー、2004年。
  12. ^ “Rubyは死んだ”のか?まつもとゆきひろ氏が語る「プログラミング言語サバイバル」とRubyの未来 - Part1 - ログミーTech
  13. ^ Ruby on Rails作者のデイヴィッド・ハイネマイヤー・ハンソンはRailsを構築するのに(Pythonではなく)、なぜRubyを選んだのでしょうか? - Quora
  14. ^ Rubyレベルのプログラミング言語はどのくらいの部分が発明者だけによるコードなのでしょうか?”. Quora (2020年9月8日). 2022年4月19日閲覧。

参考文献[編集]

  • 高橋征義、後藤裕蔵『たのしい Ruby Rubyではじめる気軽なプログラミング』まつもとゆきひろ監修、ソフトバンクパブリッシング、2002年4月。ISBN 4-7973-1408-7  - プログラム未経験者向けの入門書。
    • 高橋征義、後藤裕蔵『たのしいRuby Rubyではじめる気軽なプログラミング』まつもとゆきひろ監修(第2版)、ソフトバンクパブリッシング、2006年8月。ISBN 4-7973-3661-7 
    • 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第3版)、ソフトバンクパブリッシング、2010年3月。ISBN 978-4-7973-5740-0 
    • 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第4版)、ソフトバンクパブリッシング、2013年6月。ISBN 978-4-7973-7227-4 
    • 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第5版)、ソフトバンクパブリッシング、2016年2月。ISBN 978-4-7973-8629-5 
    • 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第6版)、ソフトバンクパブリッシング、2019年3月。ISBN 978-4-7973-9984-4 
  • デビット・トーマス、アンドリュー・ハント『プログラミングRuby 達人プログラマーガイド』田和勝訳、まつもとゆきひろ監修、ピアソン・エデュケーション、2001年9月。ISBN 4-89471-453-1 
    • Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 言語編』田和勝訳、まつもとゆきひろ監修(第2版)、オーム社、2006年8月。ISBN 4-274-06642-8 
    • Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby ライブラリ編』田和勝訳、まつもとゆきひろ監修(第2版)、オーム社、2006年8月。ISBN 4-274-06643-6 
    • Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 1.9 言語編』田和勝訳、まつもとゆきひろ監修、オーム社、2010年5月。ISBN 978-4-274-06809-6 
    • Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 1.9 ライブラリ編』田和勝訳、まつもとゆきひろ監修、オーム社、2010年5月。ISBN 978-4-274-06810-2 
  • David Flanagan、まつもとゆきひろ『プログラミング言語 Ruby』卜部昌平監訳、長尾高弘訳、オライリー・ジャパン、2009年1月。ISBN 978-4-87311-394-4 
  • まつもとゆきひろ、石塚圭樹『オブジェクト指向スクリプト言語 Ruby』アスキー〈ASCII software science : Language 11〉、1999年11月。ISBN 4-7561-3254-5 
  • まつもとゆきひろ『まつもとゆきひろ コードの世界~スーパー・プログラマになる14の思考法』日経Linux編集、日経BP社、2009年5月。ISBN 978-4-8222-3431-7 

関連項目[編集]

外部リンク[編集]