» Rubyのブログ記事

メソッドの定義方法は以下の通りです。

def メソッド名(引数1, 引数2,…)
  実行する処理
end

簡単なサンプルを書いてみます。

#メソッド定義
def printRuby
   puts "I Love Ruby"
end

#メソッド呼び出し
printRuby

実行結果は「I Love Ruby」が表示されるだけの簡単なものです。
次に引数と返値のあるメソッドを作ります。

#メソッド定義
def dice(n)
 case n 
   when 1
     a = "サイコロの目は"+(rand(6)+1).to_s+"です。"
      return a
    when 2
      a = "サイコロの目は"+(rand(6)+1).to_s+"と"+(rand(6)+1).to_s+"です。"
      return a
    else
     return "引数には1か2を選んでください。"
 end
end

#メソッド呼び出し
n = dice(2)
puts n

dice(n)でnに入力した「値はcase n」で分岐の条件に使用されます。
「return」の後ろにある値が戻り値としてメソッドを呼び出した元に返されます。
「return a」ではaに入っている値が戻値として返されます。
では前回作ったカレンダープログラムをメソッドにしてみます。

#メソッド定義

require "date"

def show_calendar(y,m)

  firstday = Date.new(y,m,1)
  lastday = Date.new(y,m,-1)

  calendar = firstday.strftime("%Y年  %m月")+"\n"
  calendar += "日 月 火 水 木 金 土"+"\n"

  if firstday.wday != 0 then
      for x in 1..firstday.wday do
          calendar += "   "
      end
  end

  for d in 1..lastday.day do
     if firstday.wday == 6 then
       calendar += sprintf("%2s ",d)+"\n"       
     else
       calendar += sprintf("%2s ",d)
     end
     firstday = firstday.next
  end

  return calendar
end


#メソッド呼び出し
for x in 1..12 do
 puts show_calendar(2010,x)
end

メソッドにすることにより簡単に1年分のカレンダーを表示できるようになりました。

Rubyでカレンダーを作るのに、「Date」クラスを使用します。「Date」クラスには日付を扱うのに便利な機能が備わっています。「クラス」というのはデータとそのデータを使った処理が書かれた設計図みたいなものです。
「Date」クラスには日付データとその処理をする命令が色々と書かれています。

require 'date'

day = Date.today#今日の日付
day1 = Date.new(2010,10,15)#指定した日付
day2 = Date.new(2010,10,-1)#月末

puts "今日の日付"
p day.year #=> 年
p day.month #=> 月
p day.day #=> 日
p day.wday #=> 日曜日が0、土曜日が6
puts "指定した日付"
p day1.year
p day1.month
p day1.day
p day1.wday
puts "月末"
p day2.year
p day2.month
p day2.day
p day2.wday

まず「require ‘date’」で「Date」クラスを利用できるようにします。「day = Date.today」では
「Date」クラスから今日の日付が入った「オブジェクト」を作成しています。オブジェクトとは設計図に基づいて
つくられた実体です。クラスを使用するにはオブジェクトを作成してそのオブジェクトを利用します。
「p day.year」では「day」オブジェクトに対して「year」メソッドを使用して西暦データを取得しています。
「year」メソッドというのは「day」オブジェクトが保持しているデータを処理する命令です。
このメソッドは予め「Date」クラスに備わっています。他にもたくさんのメソッドがあります。
「month、day、wday」も予め用意されたメソッドです。
他のメソッド詳細はリファレンス参照してください。

require 'date'

first = Date.new(2010,10)
last  = Date.new(2010,10,-1)

month = first.strftime("%Y年  %m月")+"\n"
week = "日 月 火 水 木 金 土"

puts month
puts week

if first.wday != 0 then
  for x in 1..first.wday do
     print("   ")
  end
end

for d in first.day..last.day do
   if first.wday == 6 then
     print sprintf("%2s ",d)+"\n"         
   else
     print sprintf("%2s ",d)
   end
   first = first.next
end

4行目で月末の数字が入った「last」オブジェクトを作っています。6行目の「strftime」メソッドでは日付の表示形式を指定しています。
12行目の「if」文では月の第1週目が日曜以外から始まっている場合、空白を出力しています。
18行目からの「for」文では月初から月末までの日付を繰り返し文で出力しています。
「if first.wday == 6 then」では土曜日なら日付の後ろに改行マークを追加しています。
「sprintf(“%2s “,d)」では日付の前後に半角のスペースを入れています。「sprintf」はリファレンス参照。24行目では「Date」クラスの「next」メソッドで日付を1日進めています。これでRDEのコンソールウィンドウに指定した月の
カレンダーを表示できました。しかしこのプログラムでは1年分のカレンダー表示などができません。3行目から25行目までを
12か月分書けば可能ですが非効率です。そこで次回はこのプログラムをメソッドにして繰り返し分の中の処理で呼び出すことにより
12か月分のカレンダーを表示できるようにしてみます。

ハッシュは配列に似ています。配列とちがうところは、値の取り出し方です。
配列では0から始まる数字を使って値を取得していました。ハッシュでは予め値に
名前(キー)を付けておき、そのキーで値を取り出します。

ハッシュ名 = {キー1 => 値1, キー2 => 値2}
ハッシュの作成。「キー1、値1」と「キー2、値2」の組み合わせの値が入ったハッシュが出来ます。

ハッシュ名[キー2] = 100
値2の部分に100が設定されます。

変数 = ハッシュ名[キー2]
変数に100が代入されます。

簡単なくじ引きプログラムを作ります。

kuzi = {0 => "一等、ハワイ旅行",5 => "二等、液晶テレビ",7 => "三等、商品券"}

a = rand(8)

print(kuzi[a],"\n")

キー(名前)に0、5、7の数字を使用してます。
「a = rand(8)」で0から7までの数字を作成。ハッシュから値を取得するのに使用。
このプログラム実行すると、時々「nil」と表示されます。
これは指定したキーに値が無かったり、キーその物がハッシュにない時に表示されます。
この「nil」と「if」文を使ってハズレを表示します。

kuzi = {0 => "一等、ハワイ旅行",5 => "二等、液晶テレビ",7 => "三等、商品券"}

a = rand(8)

if kuzi[a] == nil then
  print("はずれです。もう一度引いてください","\n")
else
  print(kuzi[a],"\n")
end

最後にハッシュを使って前回のシーザー暗号プログラムを書き換えます。

#シーザー暗号 ハッシュ

table = {"a"=>0,"b"=>1,"c"=>2,"d"=>3,"e"=>4,
"f"=>5,"g"=>6,"h"=>7,"i"=>8,"j"=>9,"k"=>10,
"l"=>11,"m"=>12,"n"=>13,"o"=>14,"p"=>15,
"q"=>16,"r"=>17,"s"=>18,"t"=>19,"u"=>20,
"v"=>21,"w"=>22,"x"=>23,"y"=>24,"z"=>25,
" "=>26}

key = 3

a = "I love Ruby"

a = a.downcase
i = a.length

encryption = '暗号化した文='

for x in 0..(i-1) do
   
   suzi = table[a[x].chr]
   
   crypt = (suzi + key) % 27#keyの値だけ数字をシフト
  
   encryption += table.index(crypt)
end
puts encryption

21行目ではハッシュに平文の各文字をキーとして指定し、値を取得してます。
25行目ではハッシュに値を指定し、対応するキーを取得してます。
「table.index(crypt)」の「index()」についてはリファレンスを参照してください。
前回のプログラムに比べると「while」文が無くなって処理の流れがスッキリして分かりやすくなったと思います。

前回のプログラムでは、ずらす数字を変更した場合、テーブルの文字を全部書き換える必要があります。
今回はアルファベットに数字を対応させてみます。

#シーザー暗号

table = [["a",1],["b",2],["c",3],["d",4],["e",5],
["f",6],["g",7],["h",8],["i",9],["j",10],
["k",11],["l",12],["m",13],["n",14],["o",15],
["p",16],["q",17],["r",18],["s",19],["t",20],
["u",21],["v",22],["w",23],["x",24],["y",25],
["z",26],[" ",27]]

key = 3#文字をずらす数

a = "I love Ruby"

a = a.downcase

i = a.length

encryption = '暗号化した文='

for x in 0..(i-1) do
   count = 0
   while  table[count][0] != a[x].chr
        count += 1
   end   
   suzi = table[count][1]#アルファベットに対応する数字を取得
 
   crypt = (suzi + key) % 27#keyの値だけ数字をシフト
   #crypt = (suzi - key) % 27#復号化用
   encryption += table[crypt-1][0]#シフト先アルファベット取得#[crypt-1]で-1してるのは配列が0から始まるため
end
puts encryption

前回と今回のプログラムは以下のページを参考にさせて頂きました。
Tiny Basic for Windows
「Topページ」-「プログラムの背景」-「カエサル暗号」に詳しい説明があります。
「crypt = (suzi + (key)) % 27」の計算部分について説明があるので、お勧めです。

シーザー暗号はアルファベットを一定の数、前後どちらかにずらす単純なものです。3文字後ろにずらす場合、
「ABC」は「DEF」に暗号化されます。まずは、2次元配列を使って、暗号化前の文字と暗号化後の文字を
セットにした、[“A”,”D”],[“B”,”E”],[“C”,”F”]・・・[“Z”,”B”],[” “,”C”]のテーブル
を作ります(最後の組み合わせは半角スペースとC)。これには2次元配列を使います。

a = [[0,1], [2,3], ['a',4]]
print(a[0],"\n")
print(a[1],"\n")
print(a[2],"\n")

print(a[0][0],"\n")
print(a[0][1],"\n")

print(a[2][0],"\n")
print(a[2][1],"\n")

実行結果
01
23
a4
0
1
a
4

配列の中に配列を入れることで 2 次元配列を作る事が出来ます。0番目の要素は配列 [0, 1]です。その配列の
0番目の要素が0、1番目の要素が1になります。 配列の値を取得するには「配列名[][]」で取得できます。
最初の[]に指定する数字(0,1,2)で「[0,1], [2,3], [‘a’,4]」のいずれかの配列を指定します。2番目の[]に指定する
数字(0,1)で指定した配列の値を取得します。
では、暗号化前の文字と暗号化後の文字をセットしたテーブルを作ります。

table = [["a","d"],["b","e"],["c","f"],["d","g"],["e","h"],
["f","i"],["g","j"],["h","k"],["i","l"],["j","m"],
["k","n"],["l","o"],["m","p"],["n","q"],["o","r"],
["p","s"],["q","t"],["r","u"],["s","v"],["t","w"],
["u","x"],["v","y"],
["w","z"],["x"," "],["y","a"],["z","b"],[" ","c"]]

この組み合わせは3文字づらす形で作っています。”a”の3文字後が”d”、”b”の
3文字後が”e”。”y”の3文字後は最初に戻って”a”になっています。
まずは「for」文を使用して平文の各文字を取得してみます。

a = "I love Ruby" #暗号化する文(平文)

a = a.downcase #大文字は不可なので、平文を小文字に変換。

i = a.length #for文で平文の各文字を取得するために平文の文字数を取得

encryption = '暗号化した文=' #暗号化した文字を入れる変数。

for x in 0..(i-1) do
    puts a[x].chr
end

平文の先頭から1文字づつ取得して表示することができました。
「for x in 0..(i-1) do」で(i-1)をしているのは、平文の一番最初にアクセスするには、
0から始まるため、平文の文字数、今回は10から1を引いています。
「puts a[x].chr」のchrはこちらを参照。
「a[x]」のみでは文字のアスキーコードが取得されるため、「chr」で文字に変換してます。

次に「while」文を使用して平文の各文字に対応した暗号化後の文字を取得します。

table = [["a","d"],["b","e"],["c","f"],["d","g"],["e","h"],
["f","i"],["g","j"],["h","k"],["i","l"],["j","m"],
["k","n"],["l","o"],["m","p"],["n","q"],["o","r"],
["p","s"],["q","t"],["r","u"],["s","v"],["t","w"],
["u","x"],["v","y"],["w","z"],["x"," "],["y","a"],
["z","b"],[" ","c"]]

a = "I love Ruby"

a = a.downcase

count = 0
while  table[count][0] != a[0].chr 
    count += 1
end   
mozi = table[count][1]#暗号化した文字を取得
puts mozi

「while table[count][0] != a[0].chr」ではテーブルの先頭から比較していき、平文の文字と一致した段階で
「while」文を抜けて、「mozi = table[count][1]」で暗号化した文字を取得します。
a[0]の部分の数字を変更して取得される文字を確認してください。a[3]の場合は平文の4番目の文字になるので、
「o」です。「o」に対応する暗号化後の文字は「r」になります。

この「while」文と先ほどの「for」文を組み合わせて完成です。

#シーザー暗号

table = [["a","d"],["b","e"],["c","f"],["d","g"],["e","h"],
["f","i"],["g","j"],["h","k"],["i","l"],["j","m"],
["k","n"],["l","o"],["m","p"],["n","q"],["o","r"],
["p","s"],["q","t"],["r","u"],["s","v"],["t","w"],
["u","x"],["v","y"],["w","z"],["x"," "],["y","a"],
["z","b"],[" ","c"]]

a = "I love Ruby"#暗号化する文

a = a.downcase#小文字に変換

i = a.length#文字数取得

encryption = '暗号化した文='#この変数に暗号文追加

for x in 0..(i-1) do
   count = 0
   while  table[count][0] != a[x].chr
        count += 1
   end   
   mozi = table[count][1]#暗号化した文字を取得
   encryption += mozi
end
puts encryption

暗号化した文を元にもどすには以下の変更でできます。

for x in 0..(i-1) do
   count = 0
   while  table[count][1] != a[x].chr#変更
        count += 1
   end   
   mozi = table[count][0]#変更
   encryption += mozi
end

「hello world」で感動できなかった人も、暗号化した文が、
うまく複合化できたときは少し感動できるんではないでしょうか。

2021年9月
« 4月    
 1234
567891011
12131415161718
19202122232425
2627282930  

カテゴリー

広告

現在の住まい、将来はVPSへ引越します。 ロリポップの上位版です。

広告

広告

最近のコメント

    広告

    Railsを動かす予定のVPS。無料キャンペーン中。

    広告