americandog1993の日記

プログラマー歴半年のメモ

CentOSにvimを入れる

CentOSにviとかいうやつしか入ってなかったのでvimを入れることにした。

僕の環境だと

$ sudo yum install mercurial

このパッケージだけ入れて

$ cd /usr/local/src
$ sudo hg clone https://bitbucket.org/vim-mirror/vim vim

vimをとってきて

$ cd vim
$ sudo ./configure --with-features=huge --enable-multibyte --disable-selinux
$ sudo make
$ sudo make install

Vimそのものは完了。
無事使えることも確認。

あと、絶賛Ruby修行中なのでRsenseってやつを加えた。

$ sudo yum install java-1.8.0-openjdk wget -y
$ wget http://cx4a.org/pub/rsense/rsense-0.3.tar.bz2
$ bzip2 -dc rsense-0.3.tar.bz2 | tar xvf -
$ sudo cp -r rsense-0.3 /usr/local/lib
$ sudo chmod +x /usr/local/lib/rsense-0.3/bin/rsense

RsenseはRuby環境入れてからでないとうまく入れられないっぽい(要確認)。
あとwgetのところでなぜか一般ユーザーsudoだと上手くいかなかったのでsuしてrootで叩いた。

完了。

参考
qiita.com
qiita.com

vagrant で no such device とか出てうまくいかないとき

$ vagrant up

をした時に赤文字で なんとかかんとか:no such device とか出ていろいろ不具合ったので。

qiita.com
qiita.com
qiita.com

このあたり参考にしたらいけたっぽい?
例のごとく色々試して結局何が原因で何で直ったのかわかってないんだけれども、

$ vagrant ssh

入ってから、下のやつ走らせたのが決定打っぽい。

$ sudo yum update kernel*

終わったら exit で抜けて、

$ vagrant reload

なんか色々ダウンロード始まってうまくいった。
よかったです(カスの感想)。

CentOS(6.8)で Ruby on Rails 環境構築しようとしてめっちゃハマった

www.task-notes.com

結論から言うとここのやり方でほぼいけた。
Linuxはセキュリティの観点(?)から極力rootではなく作ったユーザーで作業すべきのようだが、sudo で進めてたらなんかエラー出てうまくいかない。
ある程度Linuxの基本を勉強する必要があるんだろうな。

あんまりよくないんだろうなとは思いつつ、ほぼ全部rootで作業したらすいすい進めた。

$ vagrant ssh

で入ると最初vagrantユーザーで始まるが、

$ su

で root に移れる。
パスワード聞かれたら vagrant と打つ。

冒頭のリンク先のやり方だとrbenv落としてくるのだけ終わったらユーザ権限に戻ってるっぽいんだけど、

$rbenv install 2.2.2

僕の環境だとここで BUILD FAILED ってなって失敗した。
なのでここも su でroot権限になって実行。
すると

Installing ruby-2.2.2...

のとこでめっちゃ待たされた後うまくいった。

続いてrails

qiita.com

railsインストール」以下を愚直に打ち込んでいく。
あとは道なりに・・・と思いきや、

$ bundle install

でエラー発生。
赤い英語で何やら書いてある。
sqlite3がどうたらこうたら。

ググろう。

qiita.com

いただきましたありがとうございます。
とりあえずsqlite-develっていうのが足りてないってことっぽいのでインストールする。

$ yum install sqlite-devel

こう。
僕の場合はこの状態で

$ bundle install

で再トライしたら無事成功。
そのまま rails server までトラブルなくできた。

VirtualBox上のCentOS(6.8)で rails server した結果をホストOSのブラウザから見る

ホストOSのブラウザでゲストOSの localhost:3000 どうやって見るのってなってハマった。
解決したのでメモ。

vagrantfileに以下の設定を書き足す。

# config.vm.network "forwarded_port", guest: 80, host: 8080 

の下に

config.vm.network :"forwarded_port", guest: 3000, host: 3000

を挿入。

$ vagrant halt
$ vagrant up

再起動して

$ rails s -b 0.0.0.0

railsアプリのディレクトリでこれを実行。

f:id:americandog1993:20170416012216p:plain

ホストOS Chromeのアドレス欄に入力すると・・・

f:id:americandog1993:20170416012317p:plain

いただきましたありがとうございます。

-b 0.0.0.0 の意味はよくわかってない。
とりあえず今は動くrails環境作るの優先でいきたいのであえて深入りしないことにする。

追記
iptable 設定も関係あるっぽい?
ググりながらいろいろいじってたからどれがどう関係あるのかわからん。
あとで確認して必須っぽかったらまた書き足します。

参考
teratail.com

もし女 六村リオの緊急事態 Ruby解答

paiza.jp

『もし次の常駐先が女子エンジニアばっかりだったら』をやっていたら『六村リオの緊急事態』(Bクラス相当)で4時間くらいひっかかって(いかにも要領の悪そうな長いコードができあがり、しかも動かない)、答えを探した。
もし女に関しては解答のシェアを認められているようだが、PAIZA問題は解答をネットに書くのは厳禁なので注意。

Rubyで挑戦していたのでRubyの解答を探したが、見つからない。
公式ブログにPythonの解答例があったが、Pythonの文法が全くわからず、解読できなかった。
最終的にこちらのPHP解答を参考にした。

blog.mimsys.net

PHP経験はないが、Pythonと比べるとはるかに推測可能だった。
ほとんどパクリというか、Rubyに書き直しただけだが、以下が無事通過したRuby解答。
このブログを書いた方には本当に感謝しかない。

input_lines = gets.split(' ')
cur_arr = input_lines[0].split('/')
path_arr = input_lines[1].split('/')
for path in path_arr
    if path == '..'
        cur_arr.pop
    elsif path == '.'
        #何もしない
    else
        cur_arr.push(path)
    end
end
cur_arr.delete('') #'//'を防ぐ
puts '/' + cur_arr.join('/')

敗因はArray.popメソッドを知らなかったことだろう。
これを知るまで拡張Forで全部取り出して最後だけ削除してまた結合し直すとか意味不明なことをやってしまっていた。
ところで、

cur_arr.delete('') #'//'を防ぐ
puts '/' + cur_arr.join('/')

この最後の2行だが、例えば /home/current という入力値を .split してまた .join でくっつけるような単純な処理で考えると、まず、"/"で区切って "", "home", "current" となる。
1行目はこの頭の "" を消すための.deleteメソッドだ。
このまま .join すると home/current となってしまうので2行目の頭で "/" を加えている。
それなら最初からこう書けばいいのではないかと思える。

puts cur_arr.join('/') #=>/home/current

配列先頭の "" を残すことで、何もしなくても先頭に "/" が挿入される。
これは間違いなく正解である。少なくとも例に出したような入力値の場合は。
しかし、自動採点時に5パターンほど値が入力されるのだが、その中に "/ .." という意地悪な入力がある。
後者の書き方だと、この時に "" を出力してしまい不正解となる(正解は"/")。
先のPHP解答の記事を読んでも、この場合の処理にやや苦心された様子が伺える。

Javascript チェックボックスが未選択のままsubmitを押したら警告が出るようにする

チェックボックスがすべて空だったらsubmitさせたくない時。
まずJS。

function isCheck() {
	var arr_checkBoxes = document.getElementsByClassName("checkBoxes");
	var count = 0;
	for (var i = 0; i < arr_checkBoxes.length; i++) {
		if (arr_checkBoxes[i].checked) {
			count++;
		}
	}
	if (count > 0) {
		return true;
	} else {
		window.alert("項目を1つ以上選択してください。");
		return false;
	}
}

getElementsByClassNameはgetElementsByIdのclass版。
引数のクラス名の要素をまとめて配列で取得する。

チェックボックス要素.checkedで選択されてるかどうかの状態を示す。
選択されてたらtrue、されてなかったらfalseを返す。
trueの時、つまりチェックされてる時にcountに1ずつ足していく。

最後のif文で1つでも選択されてるか0かを見る。
0ならfalse。
ここで例えば

if (count >= 2)

とすると「2つ以上選択してください。」とかできる。

if (count === 0) {
  return false;
} else if (count > 2) {
       return false;
} else {
       return true;
}

で、「2つまで選択できます。(ただし未選択は不可)」もできる。
HTMLと合わせたらこうなる。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<script>
			function isCheck() {
				var arr_checkBoxes = document.getElementsByClassName("checkBoxes");
				var count = 0;
				for (var i = 0; i < arr_checkBoxes.length; i++) {
					if (arr_checkBoxes[i].checked) {
						count++;
					}
				}
				if (count > 0) {
					return true;
				} else {
					window.alert("項目を1つ以上選択してください。");
					return false;
				}
			}
		</script>
	</head>
<body>
	<form>
		<input class="checkBoxes" type="checkbox">会社辞めたい</input><br>
		<input class="checkBoxes" type="checkbox">すごく会社辞めたい</input><br>
		<input class="checkBoxes" type="checkbox">会社辞めた</input><br>
		<input type="submit" value="送信" onClick="return isCheck()" />	
	</form>
</body>
</html>

onClickに注意。というのも、

onClick="return isCheck()"

と、必ずreturnを入れなければいけない。
入れないとfalseの時にクリックが無効にならない。
f:id:americandog1993:20170411215032p:plain
何も選ばなかったらこんな風に出てくる。

参考:
[JavaScript] チェックボックスのチェック状態を取得する
チェックボックスを扱う-JavaScript入門