プリティーウーマンにツイーヨを読み上げてもらう
やままです。
プリティーウーマンがツイーヨを読み上げてくれるプログラムを(2ヶ月前に)つくりました!これで寂しい夜も平気です!!!
https://github.com/remain/kyoko
概要
- 任意の単語で twitter をリアルタイム検索する
- それを OS X の
say
コマンドをつかって読み上げてもらう- デフォルトだと英語しかしゃべれない
- Kyoko さんっていう日本語がしゃべれるスーパーキュートなウーマンがいるからどうにかしてインストールする(インストール方法わすれた)
きっかけ
いつだかライブコーディングで作ったんだけど、ぼろぼろすぎてくやしかったから作りなおした。
使いみち
わからん。たぶんない。
Ruby の Prime がつよい
いろいろあって Prime クラスのソースを読んでいたらとても勉強になったよ。
Prime
- 素数全体を表すクラスだよ
- 素数全体というオブジェクトは1つしか存在しえないので、シングルトンになるよ
- 利便性のため、デフォルトインスタンスのメソッドをクラスメソッドとしても使用できるよ
- Prime.new で Ruby 1.8 の Prime の互換クラスのインスタンスを生成できるよ
ソースをよむ
lib/prime.rb から必要部分を抜粋するよ。
require "singleton" require "forwardable" class Prime include Enumerable @the_instance = Prime.new # obsolete. Use +Prime+::+instance+ or class methods of +Prime+. def initialize @generator = EratosthenesGenerator.new extend OldCompatibility warn "Prime::new is obsolete. use Prime::instance or class methods of Prime." end class << self extend Forwardable include Enumerable # Returns the default instance of Prime. def instance; @the_instance end def method_added(method) # :nodoc: (class<< self;self;end).def_delegator :instance, method end end module OldCompatibility end end
シングルトンパターン
さらに抜粋していくよ。
class Prime @the_instance = Prime.new class << self # Returns the default instance of Prime. def instance; @the_instance end end end
Singleton モジュールは使わずにシングルトンパターンを実現しているよ。どうしてだろう。
旧 Prime 互換クラスのインスタンス
class Prime @the_instance = Prime.new # obsolete. Use +Prime+::+instance+ or class methods of +Prime+. def initialize @generator = EratosthenesGenerator.new extend OldCompatibility warn "Prime::new is obsolete. use Prime::instance or class methods of Prime." end module OldCompatibility end end
OldCompatibility モジュールには旧 Prime 互換のインスタンスメソッドが宣言されているよ(中略しているよ)。 これを extend することによって、Prime.new で生成したインスタンスに特異メソッドを定義しているんだね。 互換が不要になったら OldCompatibility モジュールを削除するだけで済むからつよいよ。
Singleton モジュールを include すると Prime.new がプライベートクラスメソッドになってしまうから、旧 Prime 互換クラスのインスタンスを生成するためには Singleton モジュール を使わずにシングルトンパターンを実現する必要があったんだね。
ちなみに、デフォルトインスタンスを生成した時点では Prime.initialize は定義されていないから、このとき生成したインスタンスには OldCompatibility モジュールは extend されないよ。すごいね。
デフォルトインスタンスのメソッドをクラスメソッドとして使用する
class Prime class << self extend Forwardable def method_added(method) # :nodoc: (class<< self;self;end).def_delegator :instance, method end end end
Fowardable モジュールを extend しているね。 Fowardable モジュールはクラスに対してメソッドの委譲機能を定義するモジュール。 この場合は、method_added の引数 method を instance に委譲するよ。
(class<<self;self;end) の戻り値は Prime の特異クラス。 ここでの self は Prime だから、Prime のクラスメソッドを定義するためには (class<<self;self;end) をレシーバにする必要があるんだね(class << self の中にまた class << self が出てくるからわかりづらいよね)。
Module#method_added はクラスやモジュールにインスタンスメソッドが定義されたときに呼び出されるメソッドだよ。 Prime にインスタンスメソッドが追加されると method_added が呼ばれて同名のクラスメソッドを定義、処理をデフォルトインスタンスに委譲することによって、デフォルトインスタンスのメソッドをクラスメソッドとして使用することができるんだね。
まとめ
よくわからない文体で書くのやめよう。
Ruby で文字列の表示幅をもとめるおはなし
Ruby には文字列の表示幅を求めるメソッドがありません(ニッチ)。 要は ASCII 文字を1文字、非 ASCII 文字(= マルチバイト文字)を2文字としてカウントしたいんです(ニッチ)(ニッチ)。
こんな感じで求めてみる
"hogeふが".chars => ["h", "o", "g", "e", "ふ", "が"] # String#chars で1文字ずつにばらす ["h", "o", "g", "e", "ふ", "が"].map { |c| c.ascii_only? ? 1 : 2 } => [1, 1, 1, 1, 2, 2] # ASCII 文字を1文字、非 ASCII 文字を2文字としてカウント [1, 1, 1, 1, 2, 2].inject(0, &:+) => 8 # みんなだいすき Enumerable#inject で合計を求める
できた
class String def width self.chars.map{ |c| c.ascii_only? ? 1 : 2 }.inject(0, &:+) end end "hogeふが".width => 8
だがしかし
ちょっと効率がわるい(each が2回まわる)
作戦変更
"hogeふが".chars.reject(&:ascii_only?) => ["ふ", "が"] # Array#reject で ASCII 文字を取り除く(= 非 ASCII 文字を抽出) "hogeふが".length + ["ふ", "が"].length => 8
できた(2回目)
class String def width self.length + self.chars.reject(&:ascii_only?).length end end "hogeふが".width => 8
まとめ
Enumerable#inject だいすき
CentOS 6.4 で Windows の共有フォルダをマウントしたおはなし
Windows
共有フォルダ作成
- 共有フォルダをつくります
- アクセス許可で "変更" を許可します
ファイアウォールの設定変更
Windows のファイアウォールはデフォルトだと違うセグメントからのアクセスはぜんぶ破棄するようです。違うセグメントから共有フォルダにアクセスする場合は TCP 445 をあける必要があります。これのせいでめっちゃはまった。
CentOS
Samba のインストール
$ sudo yum install samba-client cifs-utils
エントリポイント作成
$ mkdir ~/share
マウント
$ sudo mount -t cifs -o user=[win_user]%[win_password] /[win_ip_addr]//[win_shared_directory] ~/share
// アンマウント
$ sudo umount -l ~/share
fstab の設定
起動時に自動でマウントするように fstab を設定します
$ sudo vi /etc/fstab
+\\[win_ip_addr]\[win_shared_directory] /home/[linux_user]/share cifs uid=500,gid=500,file_mode=0644,username=[win_user],password=[win_password] 0 0
fstab の反映
$ sudo mount -a
Centos 6.3 に GitLab 6.0 をいれたおはなし
GitHub クローンの GitLab を導入してみました。
MySQL の GitLab ユーザ作成
# mysql -uroot -p
mysql> grant all on gitlabhq_production.* to gitlab@localhost identified by '[PASSWORD]';
mysql> exit
Redis のインストール
# yum install redis --enablerepo=epel
# chkconfig redis on
# service redis start
依存パッケージのインストール
# yum install libicu-devel
GitLab ユーザ作成
# useradd git
GitLab ユーザの git 設定
# su - git
$ git config --global user.name "GitLab"
$ git config --global user.email "gitlab@git.example.jp"
GitLab shell のインストール
$ git clone https://github.com/gitlabhq/gitlab-shell.git
$ cd gitlab-shell
$ git checkout v1.7.0
$ git checkout -b v1.7.0
$ cp config.yml.example config.yml
$ vi config.yml
gitlab_url: http://[FQDN]
$ ./bin/install
GitLab インストール
$ cd
$ git clone https://github.com/gitlabhq/gitlabhq.git gitlab
$ cd gitlab
$ git checkout v6.0.0
$ git checkout -b v6.0.0
$ cp config/gitlab.yml.example config/gitlab.yml
$ vi config/gitlab.yml
production:
gitlab:
host: [FQDN]
email_from: gitlab@[FQDN]
support_email: support@[FQDN]
$ cp config/database.yml.mysql config/database.yml
$ vi config/database.yml
production:
username: gitlab
password: ""
$ mkdir tmp/pids/
$ bundle install --deployment --without development test postgres
$ bundle exec rake db:create RAILS_ENV=production
$ bundle exec rake gitlab:setup RAILS_ENV=production
あとは Passenger とかで適に。 GitLab さんアイコンがキモいのだけゆるせない。
CentOS 6.4 で git のバージョンをあげたおはなし
CentOS 6 標準の git はちょっと尋常じゃなくバージョンがひくい(#^ω^)
もとのバージョン
$ git --version
git version 1.7.1
ひくい
忌まわしき CentOS 6 標準の git をけす
$ sudo yum remove git
RPMForgeリポジトリ追加
$ sudo rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
$ sudo rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
$ sudo vi /etc/yum.repos.d/rpmforge.repo
-enabled = 1
+enabled = 0
インストール
$ sudo yum --enablerepo=rpmforge-extras install git
あがった
$ git --version
git version 1.7.11.3
追記
epel に 1.8.2 があることに気がつきました(最近あらわれた?)。最初からこっちでいいじゃん。
CentOS 6.4 に vim 7.3 をいれたおはなし
yum のやつはちょっと古い(#^ω^)
とりあえず yum のやつを消す
$ sudo yum remove "vim*"
(略)
Dependency Removed:
sudo.x86_64 0:1.8.6p3-7.el6
ファッ!?
$ where sudo
sudo not found
sudo の霊圧が消えた
落ち着いて sudo をいれなおす
$ su -
# yum install sudo
(略)
Dependency Installed:
vim-minimal.x86_64 2:7.2.411-1.8.el6
vim-minimal さん…
# mv /etc/sudoers.rpmsave /etc/sudoers
# exit
vim-minimal さんは気にしないことにして乱暴に sudo の設定をもどした
気を取り直して vim 7.3 のソースをもってくる
公式が Linux のひとは mercurial つかうよね?ね?便利だよね?(意訳)とかいってるから mercurial でもってくる
$ sudo yum install mercurial
$ cd /usr/local/src
$ sudo hg clone https://vim.googlecode.com/hg/ vim73
ドヤ顔で mercurial でもってくる(キリッ とかいったけどはじめて mercurial つかった
公式を眺めていてあることに気づいた
2週間くらいまえに 7.4 がでている
なんかよくわからないから 7.3 にしたい。よくわからないなりに hg log
とかうったらコミットログ?がでてきたので 7.3 の最終コミットのハッシュをもってくる。よくわからないなりに hg co 29e57603bf6f
とかうったら 7.3 になった(たぶん)。
ようやくインストール
$ cd vim73
$ sudo ./configure --with-features=huge --enable-multibyte --enable-rubyinterp --enable-luainterp --disable-selinux
$ sudo make
$ sudo make install
できたよー
$ where vim
/usr/local/bin/vim
$ vim --version
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 29 2013 00:02:01)
追記
vim-minimal さんは実質 vi でした。たぶん visudo
とかあるから sudo の依存パッケージになってるんじゃないかな~