Webエンジニア目指して#48

どうもご無沙汰マンです。 ポテパンキャンプに入りました。ある程度独学した人間にとっては昔と違って旨味が激減してしまいましたが、当初よりの予定なのでいたしかたなし... 斡旋入社でキャッシュバックがめちゃ魅力的だったんだけどな、前職1年でやめるべきでした

さて未来に目を向けていきましょう、PostgreSQLなるRDBMSを導入しました。 今までSQliteだったので純粋なSQL文以外が微妙に違くてむずがゆい GUIが有料でまあまあ値が張るものしかないので嫌ですね〜

ではRubyの学習で新たに仕入れたものをメモしていきます

グローバル変数

変数にも種類があって、変数名の先頭を$にすると別rbを読み込んだ際に共有されるグローバル変数になる

testA.rb

local = "A"
$global = "A"

require_relative "variableB"

puts "ローカル変数"
puts local
puts "--------------------"
puts "グローバル変数"
puts $global

testB.rb

local = "B"
$global = "B"

実行結果
f:id:misokatsu_sand:20210802171945p:plain
testA.rbにて、$grobalを定義したあとにtestB.rbを読み込み、そこで$grobalの再定義がされるためputs $grobalの結果は"B"になった

クラス変数

@@変数名とすることでクラス内スコープの変数を定義できる
下の例のように継承しても共有できる

class Test
  @@class_name="クラス内定義"

  def set_name(name)
    @instance_name=name
    output()
  end

  def output
    puts "--------"
    puts "Testクラスによるインスタンスメソッド"
    puts "@@class_name=#{@@class_name}"
    puts "@instance_name=#{@instance_name}"
    puts "--------"
  end
end

class CopyTest < Test
  def output
    puts "CopyTestクラスによるインスタンスメソッド"
    puts "@@class_name=#{@@class_name}"
    puts "@instance_name=#{@instance_name}"
  end
end

testA=Test.new
testA.set_name("インスタンスA")

testB=CopyTest.new
testB.set_name("インスタンスB")

実行結果
f:id:misokatsu_sand:20210802182154p:plain
クラス変数の@@を@にしてみたり無くしてみたりしたが、動作しなかった。@@でちゃんとクラス変数として認識してくれるみたい

定数

変数名の頭を大文字にすると定数扱いになり、再定義ができなくなる。

Teisu = "定数"
puts Teisu
Teisu = "変更済定数"
puts Teisu

f:id:misokatsu_sand:20210802182625p:plain

配列の要素を追加する

array.push("")array << ""がある。 pushは複数要素を追加でき、<<は1つしか追加できない。 どちらも配列の末尾に追加される。

fruits1 = ["apple","banana","grape"]
p fruits1
fruits1 << "orange"
p fruits1
fruits2 = ["peach","lemon"]
fruits1.push *fruits2
p fruits1

実行結果 f:id:misokatsu_sand:20210803180145p:plain

並列の要素を削除する

array.delete_at(arrayNo.)で削除ができる

fruits1 = ["apple","banana","grape"]
p fruits1
fruits1.delete_at(0)
p fruits1
p fruits1[0]

実行結果
f:id:misokatsu_sand:20210803184323p:plain
削除した配列番号を参照すると[1]だった要素が表示されることから、nilにはならず左詰めになることがわかる。

ハッシュの要素を削除する

fruits={
  :name => "apple",
  :price => "500"
}

p fruits
p fruits[:name]

fruits.delete(:name)

p fruits
p fruits[:name]

実行結果
f:id:misokatsu_sand:20210804211019p:plain

ループ処理のnext

nextが処理されると現在のループ処理をスキップし次のループ処理へ飛ぶ

for i in 1..10 do
  if i%9==0
    p "9の倍数の出力でbreakによりループ処理を終了します"
    break
    p "出力確認"
  end

  if i%3==0
    p "3の倍数の出力はnextによりスキップされます"
    next
    p "出力確認"
  end

  p i
end

実行結果
f:id:misokatsu_sand:20210805113910p:plain
next及びbreakによりp "出力確認"は処理されない

例外処理

begin内でエラーが発生した際に、処理を終了させずrescure内の処理を実行し処理を継続させられる

begin
  number = 10 + nil
  p number
rescue
  puts $! #エラー文を表示
  puts $@ #エラー発生位置を表示
  p "エラー発生、例外処理を実行します"
end

p "end"

実行結果
f:id:misokatsu_sand:20210805115721p:plain
intにnilを足すことはできないためエラーが発生する。
それを検知しrescue内の処理が実行される。

モジュール

モジュールを定義してクラスへ適用(Mix-in)することができる 共通処理がある場合、同じコードを何回も書くことになるためモジュールでまとめるのがよさそう

module Math
  def add(a, b)
    return a + b
  end
end

class Number
  include Math #MathモジュールをMix-in

  attr_accessor :a , :b

  def initialize(a,b)
    @a = a
    @b = b
    puts "#{@a},#{@b}が生成されました"
  end
end

num = Number.new(6,1)
p num.add(num.a, num.b)

実行結果
f:id:misokatsu_sand:20210806095149p:plain

また、クラス以外でもモジュールは適用できる

module Math
  def add(a, b)
    return a + b
  end
end

num = {a:6, b:1}
num.extend(Math)
p num.add(num[:a], num[:b])

f:id:misokatsu_sand:20210806112157p:plain

ディレクトリ内のファイル名を検索・取得

rubyでファイルを上書きする際に、ファイルが存在するかどうかを確認したい1

Dir.glob("ディレクトリとファイル名(ワイルドカード可)")
これを使えばディレクトリに対してファイル名を検索し、引っかかったファイル名の文字列を配列におさめてくれる

なお、引っかからなかった場合は空の配列emptyになる

例:オブジェクトがemptyかどうかを真偽値で返す.empty?メソッドと合わせてみた

p "csvファイル名を入力してください"
file_name = gets.chomp

search_file = Dir.glob("./#{file_name}.csv")

if search_file.empty?
  p "該当するファイルがありません"
else
  p "以下のファイルが見つかりました"
  p search_file
end

整数の乱数生成

下の例の場合、0,1,2,3をランダムに生成する

rand(3)

トピックの内容が濃くなってきたのでこの辺で区切ります

ではでは。