クラス変数とインスタンス変数と時々クラスインスタンス変数

FJORD BOOT CAMPの課題の中で、クラスインスタンス変数を使用したので各変数の特徴?を簡潔にまとめてみた。

インスタンス変数

特徴

  1. インスタンス変数にアクセスできるのは、initializeメソッド、オブジェクトのインスタンスメソッドのみ
  2. インスタンス毎に独立しているため、異なるインスタンス間で変数の値は共有されない

@で始まる変数はインスタンス変数であり、特定のオブジェクトに所属しています。インスタンス変数はそのクラスまたはサブクラスのメソッドから参照できます。初期化されていないインスタンス変数を参照した時の値はnilです。

# インスタンス変数
class Capital
  def initialize
    # capital_nameがインスタンス変数となる
    @capital_name = 'Tokyo'
  end
  def capital_name
    @capital_name
  end
end
# インスタンスの初期化
yamada = Capital.new
p yamada.capital_name
#=> "Tokyo"

下記の時、yamadasuzukiインスタンスが使用する@capital_nameの値は共通ではなく、インスタンス毎にインスタンス変数の値は保持される

class Capital
  def initialize
    @capital_name = 'Tokyo'
  end
  def capital_name
    @capital_name
  end
  def change_capital_name(new_capital)
     @capital_name = new_capital
  end
end

yamada = Capital.new
yamada.change_capital_name('Saitama')
suzuki = Capital.new
# 同じ@capital_nameを参照しているがインスタンスが異なるため値は共有されていない
p yamada.capital_name
#=> "Saitama"
p suzuki.capital_name
#=> "Tokyo

クラス変数

特徴

  1. クラスとそのインスタンスがスコープになる
  2. クラス変数は異なるインスタンス間でも値が共有される
  3. クラスメソッド、インスタンスメソッド、クラス定義式内でアクセス可能

@@で始まる変数はクラス変数です。クラス変数はクラス定義の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/代入ができます。 クラス変数と定数の違いは以下の通りです。
・再代入可能(定数は警告を出す)
・クラスの外から直接参照できない(継承されたクラスからは参照/代入可能)

class Capital
  @@capital_name = 'Tokyo'
  def capital_name
    @@capital_name
  end
  def change_capital_name(new_capital)
     @@capital_name = new_capital
  end
end
# 同じ@capital_nameを参照しインスタンスが異なるが値は共有されている
yamada = Capital.new
yamada.change_capital_name('Saitama')
suzuki = Capital.new
p yamada.capital_name
#=> "Saitama"
p suzuki.capital_name
#=> "Saitama"
p Capital.capital_name
#=> これは参照できない!
# 関数の前にselfをつけると、クラスを直接参照することができる
class Capital
  @@capital_name = 'Tokyo'
  def self.capital_name
    @@capital_name
  end
  def self.change_capital_name(new_capital)
     @@capital_name = new_capital
  end
end
Capital.change_capital_name("Saitama")
p Capital.capital_name
#=> "Saitama"

クラスインスタンス変数

公式リファレンスを見る限り、クラスインスタンス変数っていう文言が見当たらないので造語なのかな🤔

特徴

  1. クラスインスタンス変数はそのクラスのみでしか参照できない。(クラスを継承したクラスではその変数にアクセスできない。)
  2. クラスメソッドからはアクセスできる
  3. インスタンスメソッドからアクセスすることはできない
  4. クラス定義式内で定義される

※詳細は、下記リンクの【まとめ】インスタンス変数、クラス変数、クラスインスタンス変数で詳しく書かれています。

参考

pgを使用したPostgresqlへのアクセス

pg を用いてPostresqlへアクセスする課題があったので備忘録として。

pgとは

PostgreSQLリレーショナルデータベースにアクセスするためのライブラリである。
君の瞳はまるでルビー - Ruby 関連まとめサイト

手順

  1. pgをインストール
    Gemfilepgを追加して$ bundle install

    # Gemfile
    # frozen_string_literal: true
    source 'https://rubygems.org'
    gem 'sinatra'
    gem 'sinatra-contrib'
    gem 'pg'
    # ruby 3.0.0以降を使用するため下記gemを追加
    gem 'webrick'
    
    $ bundle install
    Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.
    Fetching gem metadata from https://rubygems.org/.........
    Resolving dependencies...
    Using bundler 2.1.4
    Using multi_json 1.15.0
    Using ruby2_keywords 0.0.5
    Using mustermann 1.1.1
    Fetching pg 1.3.5
    Installing pg 1.3.5 with native extensions
    Using rack 2.2.3
    Using rack-protection 2.2.0
    Using tilt 2.0.10
    Using sinatra 2.2.0
    Using sinatra-contrib 2.2.0
    Using webrick 1.7.0
    Bundle complete! 4 Gemfile dependencies, 11 gems now installed.
    Use `bundle info [gemname]` to see where a bundled gem is installed.
    
  2. Postgresqlに接続
    どうやらconnectする際の引数は省略することができるみたい🤔

    # db_test.rb
    # frozen_string_literal: true
    require 'pg'
    connect = PG::connect(host: "localhost", user: "choco", password: "", dbname: "postgres", port: "")
    results = connect.exec("select * from hoge")
    results.each { |result| p result }
    connect.finish
    
    #実行結果
    $ ruby db_test.rb
    {"id"=>"1", "name"=>"hoge"}
    {"id"=>"2", "name"=>"hogehoge"}
    

標準入力をcountすると末尾にDが付与される

fjordbootcampのプラクティスを進めていく上で、標準入力($stdin.read)の値に対し、String#countを使用した際にDが末尾に出力された。

# wc.rbのコード
p $stdin.read.count('a')
# 実行結果
$ ruby wc.rb
aa
a
3D
#=> 3 と表示させたい!
  1. Dの正体🤔
  2. Dを出力させなくするには🤔

に関して、調べたみたので結果を備忘録として。

Dの正体

標準入力をcontrol - Dで終了した際、端末(ターミナル)が制御文字(^D)をcharとしてエコーしているため表示される。
たしかに標準入力を終了する際にcontrol - Dで終了したな〜 更に調べると、制御文字(^D)が出力される設定になっている模様。
stty -aコマンドから端末の設定を確認することができる。 f:id:choco0809:20220409090254p:plain echoctlが設定されているため、制御文字(^D)をcharとしてエコーしているため表示されてしまう。
eof = ^Dが入力の終了であることを表している
以上のことからDの正体は制御文字(^D)であることがわかった。

制御文字(^D)を出力させなくするには

echoctlが設定されているため制御文字が出力されるので、この機能を無効化すればよい。

# sttyの機能を無効化する際は、機能の前に - を付与する
$ stty -echoctl

f:id:choco0809:20220409091214p:plain echoctlが無効化されていることがわかる。
無効後再度wc.rbを実行すると

$ ruby wc.rb 
aa
a
3

期待通り、制御文字(^D)が表示されなくなった! ただ、上記の方法など毎回実行する端末の設定を変える必要がある...😓

ちなみにrubyプログラムから端末設定を制御することができる(別途gemが必要)を教えてもらったので、
次回はそのgemを用いて、プログラム側から端末の設定を制御してみようと思う。

ちなみに

プログラム内の値にはDは付与されていないため、あまりプログラム内では意識しなくていいかも?

VirtualBoxのネットワーク設定

経緯

VirtualBoxで作成したDebianで、下記2点を実行しようとしたが上手くいかなかったので備忘録として。

  1. Debian上でaptコマンドが実行できる
  2. MacからDebianssh接続することができる

最初はブリッジアダプタ接続で上記のことを実行しようと試してみたけど、下記のような事象が発生したため、そもそもネットワークアダプタって何?ってところから調べた。

※ちなみにブリッジ接続したときに、Debian上でaptコマンドが実行できないのはどうやらwi-fi接続が原因かも?ちゃんとした原因については不明

No ネットワークアダプタ 事象
1 NAT aptコマンドは実行できるけど、ssh接続ができない
2 ブリッジ aptコマンドが実行できないけど、ssh接続はできる

VirtualBoxネットワークアダプタ一覧

そもそもネットワークアダプタについても知らないまま、手順の通り設定していたので
VirtualBoxで使用できるネットワークアダプタ一覧について調べてみた。 下記の参考サイトが図もありとてもわかりやすかったので。

VirtualBox のネットワークアダプタまとめ

原因

結局ブリッジアダプタ接続した時にaptコマンドが実行できない原因についてはわからなかったため、NATを用いる方針とした。
ただしNATを用いると上記で記載した事象が発生したため、色々調べたところそもそもNATを使用すると外部(Mac)→内部(Debian)の通信ができないので、ssh接続することができないことが分かった。

解決策

でもNATを用いてssh接続がしたい!場合はポートフォワーディングを使用すれば解決する事が判明。ポートフォワーディングに関しては下記参考サイトを参照。
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 要はポートフォワーディングで設定したIPやPortを内部(Debian)のIPやPortに紐付けしてくれる機能。 f:id:choco0809:20220314063304p:plain 上記ではMacからxxx.xx.xx.xxxというIPで2222ポートで接続しに行った時、Debian上のyy.y.y.yy56789というポートに捻じ曲げられ、外部(Mac)→内部(Debian)の通信をすることができるようになる。

$ ssh -p 2222 -i [rsaのパス] [user]@xxx.xxx.xx.xxx
Warning: Permanently added '[192.168.10.103]:2222' (ED25519) to the list of known hosts.
Linux debian 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Mar 14 06:38:45 2022

フィヨルドブートキャンプはじめました。

掲題の通り2/15よりフィヨルドブートキャンプはじめました。

巷では卒業するのがめっちゃ難しい!って言われていたので、絶対卒業して自分のしたいことができる会社に転職しよ!って思って入会しました。

 

主にフィヨルドブートキャンで躓いたところや、アウトプット(備忘録くらい)をしていく場にできたらいいなーって感じです。

(就活でも活用できたらいいな、、、)