クラス変数とインスタンス変数と時々クラスインスタンス変数
FJORD BOOT CAMPの課題の中で、クラスインスタンス変数を使用したので各変数の特徴?を簡潔にまとめてみた。
インスタンス変数
特徴
@
で始まる変数はインスタンス変数であり、特定のオブジェクトに所属しています。インスタンス変数はそのクラスまたはサブクラスのメソッドから参照できます。初期化されていないインスタンス変数を参照した時の値は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"
下記の時、yamada
、suzuki
インスタンスが使用する@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
クラス変数
特徴
@@で始まる変数はクラス変数です。クラス変数はクラス定義の中で定義され、クラスの特異メソッド、インスタンスメソッドなどから参照/代入ができます。 クラス変数と定数の違いは以下の通りです。
・再代入可能(定数は警告を出す)
・クラスの外から直接参照できない(継承されたクラスからは参照/代入可能)
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"
クラスインスタンス変数
公式リファレンスを見る限り、クラスインスタンス変数っていう文言が見当たらないので造語なのかな🤔
特徴
- クラスインスタンス変数はそのクラスのみでしか参照できない。(クラスを継承したクラスではその変数にアクセスできない。)
- クラスメソッドからはアクセスできる
- インスタンスメソッドからアクセスすることはできない
- クラス定義式内で定義される
※詳細は、下記リンクの【まとめ】インスタンス変数、クラス変数、クラスインスタンス変数で詳しく書かれています。
参考
pgを使用したPostgresqlへのアクセス
pg
を用いてPostresqlへアクセスする課題があったので備忘録として。
pgとは
PostgreSQLリレーショナルデータベースにアクセスするためのライブラリである。
君の瞳はまるでルビー - Ruby 関連まとめサイト
手順
pg
をインストール
Gemfile
にpg
を追加して$ 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.
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 と表示させたい!
- Dの正体🤔
- Dを出力させなくするには🤔
に関して、調べたみたので結果を備忘録として。
Dの正体
標準入力をcontrol - D
で終了した際、端末(ターミナル)が制御文字(^D
)をcharとしてエコーしているため表示される。
たしかに標準入力を終了する際にcontrol - D
で終了したな〜
更に調べると、制御文字(^D
)が出力される設定になっている模様。
stty -a
コマンドから端末の設定を確認することができる。
echoctl
が設定されているため、制御文字(^D
)をcharとしてエコーしているため表示されてしまう。
※eof = ^D
が入力の終了であることを表している
以上のことからDの正体は制御文字(^D
)であることがわかった。
制御文字(^D
)を出力させなくするには
echoctl
が設定されているため制御文字が出力されるので、この機能を無効化すればよい。
# sttyの機能を無効化する際は、機能の前に - を付与する $ stty -echoctl
echoctl
が無効化されていることがわかる。
無効後再度wc.rb
を実行すると
$ ruby wc.rb
aa
a
3
期待通り、制御文字(^D
)が表示されなくなった!
ただ、上記の方法など毎回実行する端末の設定を変える必要がある...😓
ちなみにrubyプログラムから端末設定を制御することができる(別途gemが必要)を教えてもらったので、
次回はそのgem
を用いて、プログラム側から端末の設定を制御してみようと思う。
ちなみに
プログラム内の値にはD
は付与されていないため、あまりプログラム内では意識しなくていいかも?
VirtualBoxのネットワーク設定
経緯
VirtualBoxで作成したDebianで、下記2点を実行しようとしたが上手くいかなかったので備忘録として。
最初はブリッジアダプタ接続で上記のことを実行しようと試してみたけど、下記のような事象が発生したため、そもそもネットワークアダプタって何?ってところから調べた。
※ちなみにブリッジ接続したときに、Debian上でaptコマンドが実行できないのはどうやらwi-fi接続が原因かも?ちゃんとした原因については不明
No | ネットワークアダプタ | 事象 |
---|---|---|
1 | NAT | aptコマンドは実行できるけど、ssh接続ができない |
2 | ブリッジ | aptコマンドが実行できないけど、ssh接続はできる |
VirtualBoxのネットワークアダプタ一覧
そもそもネットワークアダプタについても知らないまま、手順の通り設定していたので
VirtualBoxで使用できるネットワークアダプタ一覧について調べてみた。
下記の参考サイトが図もありとてもわかりやすかったので。
原因
結局ブリッジアダプタ接続した時にaptコマンドが実行できない原因についてはわからなかったため、NATを用いる方針とした。
ただしNATを用いると上記で記載した事象が発生したため、色々調べたところそもそもNATを使用すると外部(Mac)→内部(Debian)の通信ができないので、ssh接続することができないことが分かった。
解決策
でもNATを用いてssh接続がしたい!場合はポートフォワーディングを使用すれば解決する事が判明。ポートフォワーディングに関しては下記参考サイトを参照。
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
要はポートフォワーディングで設定したIPやPortを内部(Debian)のIPやPortに紐付けしてくれる機能。
上記ではMacからxxx.xx.xx.xxx
というIPで2222
ポートで接続しに行った時、Debian上のyy.y.y.yy
の56789
というポートに捻じ曲げられ、外部(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