Programming from 30

自分の備忘録が、誰かの為になれば・・

ブロックの失敗😅【Ruby】

最近課題をやっていると頻繁にブロックを使う!ただ幾分理解足らずで、ミスばかりなので過ちを備忘録として・・・

<ブロック>とは

Rubyのコードで書かれた処理のかたまりで、メソッドに引数として値を渡す

[1,2,3,4,5,6,7].each do |i|
  puts i
end

or

3.times do |i|
   x = i * 5
   puts x
end

こんな感じで書ける。ブロックは基本do ~ endの中に行いたい処理を書き、引数として値を渡している。因みに{.......}をdo ~ endの代わりに使う事もでき、基本的には1行で完結するコードに関しては{.......}を使い、複数行にわたるコードはdo ~ endを使用!
ただ参考書やwebサイトを見て、簡単なコードを書くだけだった僕はいざコードを各段階でミスばかり!

# ブロックの中で、合計を取る!
['hoge.rb','fuga.rb','baz.rb'].each do |f|
   st = File::Stat.new(f)
   b = st.blocks
   t = b.inject{|sum,n| sum + n}
   put t
 end

オブジェクトのクラスが違うのと、謎のコードで値を取れるわけもなく、長い事ハマりました。またブロック内外部で、同じ変数を使ってしまって、前の変数の値を書き換えてしまったり。

t = 23

[1,2,3,4,5].each do |i|
   t = i *3
   puts t
 end

puts t
=> 15

てんでだめですね!
ある程度自由に記述できるのがブロックではあるけど、わかんない事を書きすぎて書いている自分も理解できなくなって切るので金輪際気を付けます!
またdo ~ end{......}では結合度も違い、エラーの原因になってしまいそうなので、気をつけたい!ブロックをdo…endで書くか{…}で書くかにより挙動が変わる例
他にもyieldprocとかもあるので、理解に達したらブログ書きます!

最近、習慣にしたい事。

今、通っているFjordBootCampでは様々な課題があって、Rubyの扱っていく中での実装手順メモ!!

どうしたらその機能を実装できるか!といきなり何かの課題をつくろうとしても作れません!

まず実装したい機能がライブラリにないかRubyドキュメントをチェック! 大体の機能は組み込みライブラリや標準ライブラリを探せば大体やりたい事が見つかる。ただ初心者の僕には読みづらさがあったり、例を探してみると英語のちょっと難しめのコードがあったり、エラーで表示されない事がある! ※現在、有志でドキュメントを作っている

図解で頭に入れる学習が好きな僕としては、Rubyの構造がわかるような図解がトップページにあったりすると捗ると試みるも、まだ理解していない事を図解できず・・・が、そんなの甘えですし、ただ読む量が足りていないだけと、知識の未定着が主な原因!頑張ります!

もし、ドキュメントから実装したいライブラリがあったり、irbもしくはpryでどう動くのか、どんな値や形式で返ってくるのかを確かめて動いたら実装! 慣れない僕はそのままQiitaや個人ブログを漁り始め、真似て打ち込みながら実行しているが、やはりドキュメントやオフィシャルサイト公式から理解し実装していく事が、Rubyを理解する近道という事なので、もっとRubyの本を読み、コードを書いて場数を踏みます!

なるべく個人ブログは参考程度に、まずはドキュメント!ドキュメントを制するものはRubyを制すと信じ、Rubyを楽しみます★

Rubyのアクセサメソッドについて

学習したはずのアクセサメソッド。

class Car
  attr_accessor :name ,:price

  def initialize(name,price)
    @name = name
    @price = price
  end
end

car = Car.new('Prius',250_000)
car.name
=> 'Prius'
car.price
=> 250_000

以上のコードを見て、バカな私は

def name
  @name = name
end

のように定義してないじゃないか!!!!!!!!!!
何で使えるんだ?!の様に変な思考に入り、混迷を極めてしまった。もしかしたらmoduleクラスのnameメソッドを使っているのかと調べてドキュメントを見ても、見当違いの事が書いてあった。悩んで解決せず、メンターの駒形さんに聞くと、「アクセサメソッドにはセッターとゲッターがあって、nameメソッドを定義していると一緒の事になる」と説明を頂き、クリアになると共に、cherry本でやったではないかと、自分のばかさにホトホト呆れるほかありませんでした。 もしかしたら同じ失敗をして時間を無駄にしようとしている人、そして自分の備忘録の為に書きました。もう忘れません! 因みにattr_accessorattr_readerattr_writerを一緒にまとめたもので、

class Car
  attr_reader :name ,:price

  # 同義
  # def name
  #      @name
  #end
  # def price
  #      @price
  #end

  attr_writer :name,:price
   
   #同義
   #def name=(value)
   #  @name = (value)
   #end
   #def  price=(value)
   #   @price = (value)
   #  end

  def initialize(name,price)
    @name = name
    @price = price
  end
end

car = Car.new('Prius',250_000)
car.name
=> 'Prius'
car.price
=> 250_000
car.name = 'Crown'   # イコールの両サイドにスペース!
=> 'Crown'

と書く事ができ、通常同義の部分はdef initializeなどの下から定義するのですが、比較の為attr の後に記述しました。 何かあればご指摘いただけると幸いです!

正規表現で注意すべき点!について

最近正規表現を学習中、初心者歓迎!手と目で覚える正規表現入門を元に学習し、少しずつ苦手意識が薄れてきました。
今回はこのサイトの最後の方に正規表現について注意すべき事

(_+|\w+)*a のように、+ や * が ( ) の中にも外にも出てくる正規表現は危険です。こういう正規表現は内部的な組み合わせの数が爆発的に増え、とんでもなく遅くなることが多い

と言及されていたので、少し調べてみました!

まずはこのような080-1234-5678電話番号のマッチングを例とし、比較する正規表現は以下の2点

①\d{3}-\d{4}-\d{4}
②.*-.*-.*

この2つの正規表現の処理の様子を見て行きたいと思います。 プログラム初心者の僕は、なるべくシンプルで簡潔である方(例の為、変な正規表現)が良いと思い②番を選んでいました。ただShin x Blogや多くの方が、正規表現は長い方が良いとおっしゃっています。 その理由をregular expressions 101で見てみます。
まずは①番 f:id:tsubasa0105:20181105183942p:plain 右上に6ステップとマッチし、これが過程です f:id:tsubasa0105:20181105184057p:plain こんな感じで正規表現を左から綺麗にマッチングされています。
次に②番 f:id:tsubasa0105:20181105184300p:plain 右上に27ステップと4倍以上の処理がかかっていて、過程がこちら f:id:tsubasa0105:20181105184453p:plain ちょっと飛ばします f:id:tsubasa0105:20181105184529p:plain

②は.*に差し掛かった時点で全てにマッチしてしまったが為に-でマッチするものがなくなってしまい、一個ずつ戻りながら、マッチングを繰り返します。このようなマッチング方法をバックトラッキングwiki と呼ぶようです。ちょっと効率悪く時間もその分かかってしまいます。
もし、もっと長い正規表現.*を多様していくと、ブログトップの引用のようにサーバーに高負荷がかかるのが容易に想像できます。
今回はわかりやすい②番のような変な正規表現で比較してしまいましたが、今後正規表現を使う際は、なるべく長く、マッチングがすぐにできるようなものを意識する必要がありますね!

わからないまま進んだ、戻り値とnil。

戻り値とnilとは一体何?

参考書やWEBサイトでちらほら見かける戻り値nil。わからないままだと気持ちが悪いのでまとめてみました。

戻り値とは

最後の式を実行した結果。全てのメソッドに戻り値は存在する!

nilとは

「全く何もない」ことを表すRubyの「値」

文字で表してもよくわかりませんが、以下の画像をまず見て下さい。 f:id:tsubasa0105:20181103004714p:plain

今の今まで二段に別れて結果が出力されている事の意味を理解していませんでした。
まず、赤い汚い文字(100均のペン)で「戻り値」と書きました!「10」と「nil」という結果が出ています!上にも書きましたが、最後の式を実行した結果が帰ってきています!「10」はわかりますが、なぜputs ' a' の戻り値が「nil」なのか?!
答えがRubyの公式サイトにあり、

=> nilは何でしょうか? これはこのコマンドの評価結果です。 putsは必ずnilを返します。

「puts」は「nil」を返すそうです。「a」はただ出力されただけのもの。素人が深入りしすぎて推測するより、そういう仕組みになっているんだと思った方が良さそう。 因みにメソッドで見てみると

①def calc(a,b)
  a + b
end

calc(5,5)
=> 10


②def output
  puts 'a'
end

output
a
=> nil

メソッド①では最後の式を実行した結果の「10」が結果で、メソッド②では上でもお話ししている通り「a」を出力しただけで、戻る値が元々決められているnilが返ります!

ただ、戻り値をreturnで指定できる

def get_value
'あ'
return 'い'
'う'
end

return
"い"

まだまだわからない事は多そうです。何かあればご指摘いただけると幸いです。

Rubyの配列の基本を見やすく整理してみました!

f:id:tsubasa0105:20181102112617p:plain 電子書籍で勉強をしていると戻ったあり進んだり、紙の本でも何ページも捲らなきゃいけないのでパッと見で分かるように書いてみました!結局ググりそう。

参考;たのしいRuby プロを目指す人のためのRuby入

さくら& Debian & nginxでhttps通信をする備忘録

FjordBootCampプラクティス備忘録

さくらVPSからnginxのSSL化まで

WEBのことを知る上でいくつもの課題があり、一段落したので忘れないように、思い出しながらの備忘録
参考も乗せながら、なるべくシンプルに書いて行きますますが、結構長くなる予定。

1.さくらVPSに登録し、Debianインストール

まずはここから登録!データごとに別れているけどお好きなプランを選んで、カード決済すると②週間無料になっている。一応確認!お試し期間のみの利用であれば、会員トップメニュー→契約情報→キャンセルで簡単に解約可能。 参考:ネコでもわかる!さくらのVPS講座 ~第二回「サーバーをさわってみよう!」 | さくらのナレッジ

2.次にDebianインストール

カスタムOSインストールガイド - Debian 8 / 9を参考に最新のDebianをインストール 注意点: - 十字キーでの操作で - Graphical installを間違って押さない - rootとユーザーパスワードは別

3. Debianにsudoとvimをインストール

参考:sudoをインストールしvisudoで使えるようにする

# apt update
# apt install sudo
# adduser username sudo
# apt install vim

vim /etc/sudoersroot ALL=(ALL:ALL) ALLのしたにsubasa ALL=(ALL:ALL) ALLを追加。

4.ssh設定

参考:SSHなるものをよくわからずに使っている人のための手引書

Debian操作よりMacでの操作を先に!

$ mkdir ~/.ssh
$ ssh-keygen -t client_rsa -b 4096 
$ passwordを打ち込む

Mac秘密鍵を記憶
$ ssh-add -K ~/.ssh/client_rsaでパスワードを尋ねられるので、先ほど設定していたパスワードを打ち込む!
Mac側→Debian側 公開鍵をコピー・サーバ側に設置

$ scp ~/.ssh/client_rsa.pub remote-user-name@serverIP-address:~/.ssh/client_rsa.pub

次はDebianにインストール

$ sudo apt update
$ sudo apt install ssh

~/.sshディレクトリを最初に作成後

$ mkdir ~/.ssh
$ chmod 700 ~./ssh
$ cat client_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys

バックアップ取って、sshd_configに設定

$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_bk
$ sudo vim /etc/ssh/sshd_config 

①PermitRootLoginをnoに変更 ②port番号変更 → 攻撃対策の為 ③PasswordAuthenticationをnoに変更 ↓ sudo /etc/init.d_ssh restartで適用!!
$ ssh -p <port-number> <user-name>@<serverIP-address>にアクセスできるか確認! 注意: ①scp -Pssh -pPが大文字か小文字かではまったので注意! ②なるべくmac側の設定から行うとconnection refugeされない

5.nginxインストール

参考:Debianで最新版のnginxをapt-getを使ってインストール  wgetを使用しインストール

$ apt-key add nginx_signing.key
$ sudo apt-key add nginx_signing.key
$ sudo vim  /etc/apt/sources.list

以下を追加

deb http://nginx.org/packages/debian/ stretch nginx
deb-src http://nginx.org/packages/debian/ stretch nginx

変更を加えたので更新します! sudo apt-get update nginxをインストール sudo apt-get install nginx インストールできたか確認! $ sudo nginx -v

$ sudo service nginx status
● nginx.service - nginx - high performance web server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: http://nginx.org/en/docs/

動いてないのでsudo /etc/init.d/nginx startで起動! f:id:tsubasa0105:20181014183632p:plain できました。

6.ドメインを取得してnginxでVirtulHost

参考:プログラミングビギナーNekoteniがあなたに贈る!NginxでVirtual Hostの巻 全体的なディレクトリを視覚的にわかりやすく説明してくれている! - 新しく取得したドメインお名前.comのネームサーバを登録 f:id:tsubasa0105:20181014210139p:plain

  • ディレクトリ作成や設定ファイルに関しては上記のサイトを参考に実行し、Chrome(ブラウザ)でアクセス!間違いがなければtsuba.workのページが表示されるはず!

7. nginxでSSL

簡単な図解 f:id:tsubasa0105:20181015225657p:plain

  • やること
    秘密鍵(Private Key):server.keyを取得
    Certbotサーバ証明書(CRT):server.crtを取得
    ③ 以上2点を設定ファイルの反映
    ④ httpとhttpsで表示されるhtmlを2種類用意

  • Certbotをgitでインストール
    使用コマンドを羅列

$ sudo apt update
$ sudo apt install git
$ git clone https://github.com/certbot/certbot
$ chmod 700 ~/certbot
$ cd certbot
$ ./certbot-auto certonly --standalone -t

鍵が作られているか確認

$ sudo ls /etc/letsencrypt/live/tsuba.work/
README  cert.pem  chain.pem  fullchain.pem  privkey.p
  • Nginxの設定ファイルを変更
server {
    listen    80 ;
    server_name  tsuba.work;

    #charset koi8-r;
    access_log  /var/log/nginx/tsuba.access.log  main;
    location / {
        root   /home/demo/public_html/tsuba.work/public/; 
        index  index2.html index.htm;
        charset UTF-8;
    }

 
server {
    listen    443 ssl ;
    server_name  tsuba.work;

    #charset koi8-r;
    access_log  /var/log/nginx/tsuba.access.log  main;
    ssl_certificate /etc/letsencrypt/live/tsuba.work/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/tsuba.work/privkey.pem;
    location / {
        root   /home/demo/public_html/tsuba.work/public/; 
        index  index.html index.htm;
    }

こんな感じの設定でSSL完了
f:id:tsubasa0105:20181015230518p:plain はまったのは80番と443番ポートのファイルの置く場所。両方の表示で違うhtmlを表示させる際、root /home/demo/public_html/tsuba.work/public/;publicと違うフォルダを作成し、rootの記載を間違えてしまったことでの文字化けや、defaultのhtmlがなぜか表示されるといったエラーに遭遇。しっかりとパスとフォルダをつくる場所を確認! 以上。