ラベル ruby の投稿を表示しています。 すべての投稿を表示
ラベル ruby の投稿を表示しています。 すべての投稿を表示

2016年6月11日土曜日

LT駆動開発 26 - Extended 報告会 後朝祭で発表してきました。

LT駆動開発 26 - Extended 報告会 後朝祭で発表してきました。

今回は前日に2本のLTを仕上げるという、むっちゃ忙しい中がんばりました。

一つ目は、Simの容量が気になって安眠できないとして、ちょっと話題になった0Simの容量警告スクリプトを作成した内容を話しました。
スライドはこちら。
そのうちアプリが出るだろう。とおもっていましたが、一向に出る気配がないので、容量をチェックして、2か月未利用だと警告メールを送るスクリプトを作成しました。
どうせ作るなら、今後の応用ができるように、Rubyでスクレイピングやmechanizeで認証突破、SQLiteやメール送信など一通りの基本機能を盛り込みました。

次に、去年OSC島根でGetしたSRAMで遊んだ内容を話しました。




SRAMはDRAMに比べて扱いやすい。という話はよく聞きますが、果たして本当でしょうか??
という素朴な疑問を持ち続きて数十年。実物を入手し、Arduinoで実験しました。

たしかに前回チャレンジしたDRAMより圧倒的に簡単でしたが、すっかりC言語を忘れていたのでかなり苦戦しました・・・・
疑問に思ったことを仮説を立てつつあれこれ調べながら試行錯誤するのは楽しいですね。




2016年4月20日水曜日

Rubyでハッシュキーにシンボルを使った場合、代入式を短縮できる。

Chefのレシピをメンテしていて、Rubyのよく分からないものの一つにシンボルがあります。

で、これ、ハッシュ配列と組み合わせると、初心者にはよくわからないものになります。

a = { :A => "a", :B => "b"}

これは、シンボル:Aにaを代入しています。これはまぁOK。

a = { A: "a", B: "b"}

=>が消えまして、そのかわり前にあったコロンが後ろにつきます。
これは、=>を短縮したものなんですが、前にコロンが付くものがシンボルと思っていると訳が分からなくなります。

これの値を取り出すのは、 a[:A]になります。

ハッシュ配列に似たもの?として、構造体があります。
構造体はC言語の授業でならった人も多いと思います。

a = Struct.new(:ID,:Name)
rec = a.new(123,"taro")
pp rec.ID
みたいな感じで使います。
組み合わせて、ハッシュ配列に構造体を入れたり、配列を入れたりできます。
個人的には、a.bみたいな感じで値を取り出せる構造体が好みなんですが、Ruby的にはハッシュ配列が良いようですね。いろんなコード見ていますと。
(まぁ構造体だとメソッドとパッと見区別がつきにくい。てのがあるのかも)

最後に、Chefのレシピをメンテしていて、

a = {a: "a",b: "b}"
pp a.fetch(:a)

のようなコードを見て、なんでa[:a]じゃないんだろ?と疑問に思い調べてみました。
[]の場合、キーが存在しない場合、nilが帰ってきて、例外になりませんが、fetchの場合、key not found例外が発生します。
きちんと例外処理をしたい個所では使い分けないとなと思います。

参考:Rubyのややこしい配列とハッシュとシンボルについて整理してみた



2016年2月13日土曜日

AWS SDK for RubyでELBの作成や証明書の更新をするスクリプトを作成してみた。

クラウドを使う醍醐味はAPIでインフラを制御できる征服感だとおもっています。

というわけで、自動化、省力化をぼちぼち進めているのですが、前回S3+CloudFrontをやったので、
今度はELBに挑戦です。
といっても本業ではまだ実は使ったことがなかったりしますが・・・

今回もAWS SDK for Ruby V2をつかっています。
ELBの証明書更新作業は、早くAWS Certificate Managerが東京リージョンに来てくれれば開放されるのですが・・・

ELBの証明書更新スクリプトはここにあります。


また、ELBの作成スクリプトはここです。

EC2の作成スクリプトは既につくってあるので、これと組み合わせればちょっとしたオーケストレーションツールが作成できます。
あとはオートスケールとAnsibleスクリプトを組み合わせれば、ほぼ自動化できます。パチパチ~








ま、効率上げても首絞まるだけなんだけどね(ボソッ・・・


2015年12月27日日曜日

AWS-SDK For Ruby V2に対応してみた。

AWS SDK For Rubyのバージョンが2にあがってはや一年がたとうとしています。
AWSなどのクラウドサービスはAPIを叩いて自動化が出来るのがメリットのひとつでして、
自分も簡単なスクリプトを作成して自動化、省力化をしています。

そんな中、AWS SDK For Rubyのバージョンが2に上がり、これまでのバージョン1とは互換性がない為、絶賛稼働中のものや、作りこんだChefのレシピなどは簡単に移行できませんし、
テストも容易ではなかったりします。

しかし、いつまでもバージョン1を使い続けると、いつかは切られてしまうので、練習がてらGitHubにあげているものをバージョン2に対応させてみました。

一応バージョン1とのDIFFはこの辺りにあります。
バージョン2でcoreとリソースに分離したのですが、いまいちリソースの使い方というか使い勝手が分からなかったので、coreのみで作成しています。

バージョン1と2での大きな違いは、バージョン1では大抵戻り値としてインスタンスのオブジェクトが返っていたのですが、バージョン2では単なる構造体が返って来ます。
あと、バージョン1ではステータスの変化を検知するためにウエイトをかけたりループをまわしたりしていましたが、バージョン2ではwait_untilという専用メソッドが追加されています。

今まではいろんなリソースタイプやコレクションをそれぞれ組み合わせて叩いていたので結構大変でしたが、バージョン2では引数として文字列か数値がとシンプルになっていますし、Filterオプションが強力になっているので、全体的に短い行数で書けるようです。
ただ、今まで戻り値がオブジェクトだったので、チェーンメソッドが書けたのですが、そういうわけには行かなくなりました。

ただ、バージョン1と2でのメソッドの対比表みたいなものは無いので、バージョン1でのこのメソッドに該当するメソッドはどれか探すのが地味に大変です。
同じメソッド名のものもあれば、ec2.instance.create->ec2.client.run_instancesのようにまったく違うものもあります。

単純に置き換えは難しそうですが、この記事が少しでも役に立てればと思います。


2015年12月26日土曜日

RubyのOptionParserで地味にはまった

今まで動いていたのに、オプションを増やしたら謎の挙動をして、数時間を無駄にしたのでメモ。

Rubyでコマンドライン引数処理をするのに、optparseを使う人が多いと思います。

こんな感じで使います。

require "optparse"
opts = OptionParser.new
# 引数
opts = OptionParser.new
instance_type = nil
opts.on("-t","--instance_type INSTANCE_TYPE") do |type|
  pp type
  instance_type = type
end
# よく忘れるパーズ実行
opts.parse!(ARGV)
これで、たとえば
ruby hoge.rb -t t2.small
見たいにすると、instance_type変数にt2.smallという値が入ります。
opts.onの第一引数にはショートオプションを、第二引数にはロングオプションとオプションの説明を入れます。
--からはじめるとロングオプションとして認識します。
ロングオプションはどのオプションか一意に決まる長さまで指定すれば良いです。

で、ここでオプションを増やします。
private_ip = nil
opts.on("-ip","--private_ip PRIVATE_IP_ADDRESS") do |ip|
  pp ip
  private_ip = ip
end
さて、これは正しく動作しません(笑)
ruby hoge.rb -ip 192.168.0.1
としても、private_ipには何故か"p"という文字が入ります。
ruby hoge.rb --private_ip 192.168.0.1
だと正しく動き、private_ipには"192.168.0.1"という文字が入ります。
大抵デバック時には引数を埋め込むため気づきませんでしたが、
ショートオプションはアルファベット1文字しか有効ではなく、それ以降の文字列は引数と認識されます。

なので、
private_ip = nil
opts.on("-i","--private_ip PRIVATE_IP_ADDRESS") do |ip|
  pp ip
  private_ip = ip
end
と同じ挙動になり、-ipというオプションは-iオプションに引数pを渡していることになります。

え?常識(汗

よく見たらマニュアルにちゃんと書いてありましたね(汗

ショートオプションの引数指定は使いにくいので、このような場合はロング オプションの方が使う方もわかりやすいです。例えば、上記の場合、-ab を 指定すると -a b と解釈されます。-a が引数を持たない最初の例なら -a -b と 解釈されます。






2015年5月10日日曜日

ServerSpecでテスト内容を共通化した雛形を作成してみた。

最近ServerSpecが面白くて、色々弄繰り回しています。

ServerSpecは、デフォルトだと1サーバごとにテストを書いていく構成になります。
これだと、サーバA、サーバBそれぞれにApacheのテストを書くとすると、同じものを2つコピペしないといけなく、なんとなく無駄です。

というわけで、公式にも書いてあるのですが、テストコードを機能ごとに共通化し、テストするサーバごとに使い回しが出来るようにした雛形を作成したので、このあたりに置いておきます。

ついでに、AmazonLinuxがRedhatと判定されると、AmazonLinuxのバージョンによって、Apacheのパッケージ名が違ったりする場合の条件分岐が辛かったので、ServerSpecの中にあるSpecInfraに手を入れて、AmazonLinuxの場合、Amazonと判定させかつ、バージョン番号を取得できるようにしました。
ただ、この修正は既存のテストコードに影響が出そうなので、プルリクするかどうかは悩み中・・・


*2015/05/12 追記
テストに引数を渡せることが分かったので、引数を渡すサンプルを追加。
これで、ポートやパッケージなどのテストを共通化できるようになった。

*2015/06/16 追記
AmazonLinux判定とバージョン取得のプルリクを投げてみたところ、本家にて再実装されました。
ServerSpecに手を入れなくてもテストコードをうごかせます。

2015年5月7日木曜日

LT駆動開発14でServerSpecを紹介してきた。

前日夜にLTしないのか?と圧力お誘いがあったので、
3時間ばかし徹夜して、LT駆動開発14でServerSpecについて軽く紹介LTしてきました。

スライドはこちら。



プログラムの世界ではTDD(テスト駆動開発)と呼ばれる手法があり、
インフラがコードで制御できるのであれば、そのテストをするのが当たり前。という流れになってきています。

私自身、インフラの自動化をするに当たり、どうしても手作業でしないといけない箇所や、
勘違い、凡ミスが発生し、テストの必要性は認識していましたが、
テストの書き方がわからない。そもそも良く分からない。
という正直面倒くさいありがちな理由で後回しにしていました。

しかし、Chefで何十台とサーバを構築していると、Chef的には正しいのに、サーバがうまく動かないということが時々起こります。
大抵はドキュメントルートのパスをミスっていたなど凡ミスなんですが・・・

なので、いい加減テスト真面目にしないとなぁ。とChefDK ハンズオン with すごい広島で勉強したり、自宅で復習したりしていたのですが・・・
ChefのテストはChefSpec、サーバのテストはServerSpecとほぼ同じ内容を別のテストでやるのがとても面倒で(ぉ
まずは簡単そうなServerSpecからはじめました。
ちなみに、何でわざわざChefと、それで作られたサーバをそれぞれテストしないといけないのか?ですが、Chefのレシピが正しくても、それを組み合わせて構成したサーバが要件どおり動くのかは別問題だからです。
ChefSpecを単体テストというなら、それを複数結合して構成したサーバはServerSpecで結合テストするイメージです。
あと、レシピ以外で手動構成した箇所はServerSpecでないとテストできませんね

ServerSpecのいい点は、SSHさえつながれば、特別なエージェントなど不要。という点です。
つまり、今動いているサーバに影響を及ぼすことなくテストをすることが出来ます。
また、Windowsな人はCygwin上からでもテストを実行することが出来ます
はい。Winだからとやらない理由がなくなりました(笑)

肝心のテストコードの書き方ですが、Apacheのテストコードが雛形として生成されるので、
それと、リファレンスを見ながらで何とかなります。
プログラムと違い、サーバは機能がある程度決まっているので、テストする項目も決まってますが、
いわゆる境界テストのようなものはサーバにはないので、何を何処までテストするのか?というのが今悩んでいるところです。

Chefで担保できるところ(設定ファイルとか)はChef側で、サービスの登録や起動の有無などはServerSpecで。という感じがいいのかなぁ・・・
ま、書いたテストは消せるけど、無いテストはテストできないので、今はとりあえず思いつく箇所のテストを書いています。勉強にもなりますしね。






2015年3月29日日曜日

AMIからEC2インスタンスを起動するスクリプトを作ってみた。

毎回毎回AmazonLinuxのAMIからぽちぽちEC2インスタンスを作成するのが面倒なのでスクリプトを作りました。

かなり荒削りだけど、とりあえず目的は達成。

コードはこのあたりから参考にしました。

インフラの自動化って楽しいですね!






(・・・人ふやせよ・・・)

2015年3月8日日曜日

最近自動化がマイブーム。

明日の早朝に対応してそのまま出社。という例によってアレな事案のため、
某所の結婚式二次会的なイベントで岡山へ行く電車内で開発したEBSのディスク容量を拡張してくれるスクリプトです。

ただし、作りがおかしいのか、AWS-SDKの仕様なのか、AWSコンソール上ではステータスが変わっているのに、時々ステータスが取得できない。スクリプト処理中にAWSコンソール上で別のEBS操作すると、それのステータスがどうも帰ってきているっぽい。など、若干怪しい部分があるのと、resize2fsなどは手動でやる必要があります。


しかし、インフラ自動化って楽しいですね。

2014年9月17日水曜日

Rails4+DeviseでActiveDirectory(LDAP)認証を試してみた。

Rails4+Deviseで、ActiveDirectory認証を試してみました。

ActiveDirectoryはユーザ名がcnではなくてsAMAccountNameなんて項目に入っていたり、
標準でうっかり日本語でユーザつくろうものなら嵌ること間違いなしな罠が地味にあります。

幸いRubyは日本製なので、日本語でも問題ありませんでしたが・・・


詳細はWiKiにまとめておきます。

2014年9月15日月曜日

俺的メモ:RailsでCronで動かすバッチ処理を書きたい。でもActiveRecordは使いたい。

RailsなWebアプリケーションフレームワークでcronで動かす前提なバッチ処理プログラムを書くという変態奇特な方がいらっしゃったのでメモ。

【Rails】バッチ処理を実装したいけどActiveRecordを中で使ったりもしたいし


RAILS_ROOT/lib/tasks/直下にdel_user.rbってな感じで作成する(実は/lib配下ならどこでもいい)
実行は

rails runner Tasks::DelTmpUsers.execute

な感じ。
クラス名は、/lib/に作成したディレクトリ名の先頭大文字にしたもの::Hogehogeって名前にしないといけない。

例えば、/lib/crontask/hogehoge.rbに配置したら、
クラス名は
Crontask::Hogehoge
になる。

注意点は、モデルクラスの読み込みはされないので、使うモデルはrequireしないといけない。

Railsのテストサーバ(WEBric)はシングルスレッド?!

このところ、Rails漬けな生活を余儀なくされつつあって、四苦八苦しながら日々少しづつ山を崩していますが、地味にハマったのでメモ。

Railsな人には常識なのかもしれませんが、Railsの開発サーバである、WEBrickは、実はシングルスレッドで動作しているので、同時に複数のリクエストを処理できません。

なお、当然これはWEBrickの制約なので、Rails自体がマルチスレッドで動作しないわけではありません。

簡単に実験してみました。(Ruby 2.1.2 + Rails4)

rails g controller test1 index
rails g controller test2 index
っと、2つページを作成し、test1のindexアクションにこんな感じでスリープを入れます。


class Test1Controller < ApplicationController
  def index
    sleep(30)
  end
end

rails s
でWEBrickを起動し、localhost:3000/test2/indexにアクセスします。
普通にtest2のページが表示されるはずです。
では、その状態で別のブラウザまたは別のタブを開いて、localhost:3000/test1/indexにアクセスします。

開くのに30秒ほどかかるはずです。

では、test1にアクセスして、読み込み中のときに、test2を開いてみましょう。
おそらくtest2も応答待ちになったと思います。

ちなみに、Productionモードで起動しても同じでした。

開発用簡易サーバということで、あまり負荷がかかるのを想定されていないのでしょうが、
コントローラに重いトランザクション処理をさせて、別ブラウザで他のページを参照するテストが全く動かなくて焦りました・・・
(RubyというかRails的には、そもそも長時間サーバを専有するようなコードは書くべきではないし、やるなら別スレッドで非同期処理しろってことなんでしょうけど。)

なお、Apache+Passengerの環境では、普通にマルチスレッドで処理されるので、上記のような問題はありませんでした。

開発サーバでもマルチスレッドで動作させたい場合は、unicornなどを使用すると良さそうですが、
開発マシンのメモリがガシガシ食われるのでvagrant環境だとちょっと厳しい。


2014年6月5日木曜日

2014年6月1日日曜日

Railsで自己認証局+自己証明書を発行するWebシステムを作ってみた。

このところ色々忙しくて、ネタはあったのですが中々書けていませんでした。
まぁ表題の通りなのですが、練習がてら、Railsで自己認証局(CA)+自己証明書を発行する俺得ツールを作成してみした。

実はRailsで作るのは初ですw
ソースはこちら
作りたい!という勢いだけで作ったので、まだバグや動作がおかしいところがあります。
当初Herokuにおいておいたのですが、どうもデータが永続的に保存できないようで、
自宅サーバに試験的においています。

これはなんなのか?というと、AWSなどの仮想サーバにChefなどでサーバを大量生産できるのに、SSL証明書のテストをするためにいちいちOpensslコマンド叩くのがいい加減面倒になったのと、地味に自己認証局を建てるのがしんどかったので。

SSLのテストだけであれば、自己証明書だけでいいのですが、実際のサーバにはCAもセットします。
Chefのレシピとかで証明書のセットを作成していると、そこのテストができないんですね。
適当につくると、最近のブラウザは賢くて開かなかったりしますし・・・

あと、Webアプリなので、手元にLinuxやCygwinがいらないですし、いつどのサーバの証明書を作成したのか管理できるようになります。

現在、証明書の有効期限は意図的に短く設定しています。
これは、さすがに自己証明書を1年を超えて使わないだろうという前提があるからです。

応用すれば、クライアント証明書を発行したりもできると思います。

2014年5月2日金曜日

AWSのEC2インスタンスをスケールアップ、ダウンするRubyスクリプトを作成してみた。

GW中のサーバ高負荷に対応するため、実質自宅待機を命ぜられたので昨夜ついカットなって作ってしまった。(ほぼ丸パクリですがw)
AWSでオートスケールでない単独サーバをいったんストップし、インスタンスタイプを変更して起動させます。
ソースはここにおいておきます。



これのいい点は、オートスケール組める程の予算がない又はアプリの制約で複数台構成が取れない場合で、予めイベントなどでアクセス集中が予想される場合、従来は深夜ゼロ時に手動切り替えしていたものがスケジュール化出来ます。

2013年11月9日土曜日

RubyのUFO演算子を利用したソート処理について

今日、長年?の疑問がひとつ解消したが、また忘れそうなのでメモ。
Rubyでイテレータを使ったソートのコード。
例えば、以下のコードは文字列配列arrayの中身をアルファベット順にソートする。

array=%w(R U B Y)
sorted=array.sort{|a,b|
a <=>b
}

これ、実はよく分かっていなくて、ずっと引っかかっていた。
イテレータなのだが、よく処理を渡すと説明がある。

以下疑問点
・処理を渡す引数は何処?|a,b|のaとbに何か渡すの?
・突然出てくる、a<=>bの箇所が不明。UFO演算子でA < Bならば負の数を返し、
A > Bならば正の数を返し、AとBが等しければ0を返す。は分かるが、その戻り値は何処に返っているの?
・a<=>bでアルファベット順に並べるとあるので、これ自体がアルファベット順に並べる命令?とすると、数字を並べるのは1<=>2とか??
・そもそも、ソート処理にブロックを渡しているのが違和感がある。
・イテレーターってループ処理のことじゃなかったっけ??

今となってはかなりアホな疑問なのだが、ついさっきまで理解できていなかった。
(なので、定型句としての理解だった)

a<=>bというのは、上記の通り2つの値を比較するもの。
数字や文字コードなどの比較を行い、その大小に応じて、-1,0,1を返す。
http://docs.ruby-lang.org/ja/search/query:%EF%BC%9C%EF%BC%9D%EF%BC%9E/

で、これ、ソートの判定条件をセットしているんです。

っといっても、鈍感な私はピンと来なかったわけです。
で、こいつを分解していきます。

sorted=array.sort{<ソートする判定条件>}
これが最初の疑問処理を渡す引数は何処?の答え。
では、その中身がどういう動きをしているのか書いてみる。
簡単なバブルソートの例ですが。

array=%w(R U B Y)
cnt=array.size-1
for i in 0..cnt
  for j in 0..cnt -i -1
    case array[j]<=>array[j+1] #ここ
    when +1 then
      swap=array[j]
      array[j]=array[j+1]
      array[j+1]=swap
    end
  end
end

2番目の疑問。
こいつ自体は、ソート時の判定処理に組み込まれる。
この例では、+1の時しか役に立っていないが、+1,0,-1を返すことを期待されている。
ここまで来ると、3つ目の疑問が自ずと解消される。
これは、
|a,b|
A~Bという意味ではなく、単なる変数で、array[j]とarray[j+1]がセットされる。
なので、別に|z,a|でも良い。
そして、次の
a<=>bが結果的に
array[j]<=>array[j+1]
となり、上記のcase文判定条件となる。

4つ目の疑問。
これはソート条件をプラグインで差し替えることを目的としている。
例えば、
a<=>b
の箇所を
a.length<=>b.length
にすると、結果的に
array[j].length<=>array[j+1].length
となり、文字列長での並び替えとなる。

処理を渡すと言われると、上記のコードを丸々変数か何かに入れて渡すとかをイメージするので、訳が分からなかったが、
上記コードが遮蔽されていて、判定条件部分を渡すのなら合点が行った次第。


ちなみに、UFO演算子は宇宙船演算子が正しい??






2013年4月7日日曜日

広島Ruby勉強会#031に参加してきました

広島Ruby勉強会#031に参加してきました。

今回はなんと、最年少14歳の方が参加されておりました。
(自分が中学生の時は何やってたんだろと・・)
スイス人の方もいらしたり、やっぱり本場の英語は発音が違うな〜と>そこか



今回、「PHPのレガシーコードをRubyで焼き変えてみた」という内容で喋らせてもらいました。
内容は15分程度で終わらせる予定でしたが、毎度のことながら脱線しまくりで結局30分超しゃべってしまい、
後の人に迷惑をかけてしまいました・・スミマセン

いやぁ、勉強した手の頃に書いたコードって痛いですね(笑)
中二病的な痛さですね。俺凄い!とか当時本当に思っていましたからね。
今見ると相当酷いコードでした。半分ネタだったとはいえ、正直何度か挫折しかけました。
(俺の屍を超えてゆけ・・)

今回の教訓:

コードレビューは大事!


テストも無いようなレガシーコード。非常に厄介です。そのコード、中二病入っていませんか?



2012年10月14日日曜日

RubyでAquesTalkを喋らせてみた。

昨年のPHPカンファレンスで東京に行った時仕入れいた、合成音声LSI AquesTalk
喋らせてみた。

これ、おもしろい!
こんな小さな8bitマイコンで、外付けのROMやRAMがいるわけもなく、電源とシリアルをつないで、
ローマ字を送るとしゃべる。
こんな小さな容量にどうやって詰め込んでいるのか。正に謎の技術。
しゃべるといえば、昔、PC6001というマシンがあって、これがBASICでTALK文という命令を使うと
喋らせることができた。当時画期的で大変未来を感じたものだ。こんな動画もある。
さらに、当時5インチフロッピーな時代に3.5インチフロッピーだったマッキントッシュは喋るのだよ。
衝撃だった。
ディスプレイがカラーになった時や、FM音源がなった時の感動は今でも・・・

っと昔話はおいておいてw
こいつを喋らせるには、音声記号と呼ばれるローマ字にアクセント記号がついたものを送る必要がある。音声記号の仕様についてはここを参照。

で、公式にも日本語を音声記号にするサービスがあるのだが、
サーバー資源に限りがあるため、本サイト以外からのアクセスおよびアプリやスクリプトからの利用を禁じます。
とのことなので、自作してみた。

ソースはここで公開中。お気軽にpull requestやらforkしてね。

仕組みとしては、

  1. TwitterAPIを利用して、特定ハッシュタグのついたつぶやきを取得。
  2. MeCabを利用して形態素解析を行う。
  3. 形態素解析の結果、数字なら数字のタグをつける。英語なら英語のタグをつける。
  4. 形態素解析の結果、記号で読み方がわかるものはそのまま。読めない記号は無視。
  5. 形態素解析の結果、記号で読み方が不明の場合は、人間が読み方の辞書を与える。
  6. 形態素解析の結果、固有名詞の場合は読み方がわからないので、人間が読み方の辞書を与えてやる。
  7. kakasiを使って、読みがなをローマ字に変換する。
  8. シリアルポートへローマ字を流して喋らせる

ざっとこんな感じ。
何気に公式に対抗してみるw
公式より優れているw点

  • 英語タグの解釈が可能
  • 記号の読みにある程度対応(辞書のメンテ次第)
  • intelのような英語固有名詞にある程度対応。(辞書のメンテ次第。公式も一部対応の様子。)
  • 公式ではデータシートにない裏コマンドを生成する?(MODE=DaAってなんだ?)


公式より劣っている点

  • アクセント未対応(アクセント辞書どこかにあるのかなぁ)
  • 公式でも一部対応しているようだが、膨大にある英語よみの辞書を手動メンテしないといけない。(どこかに辞書が落ちていないかなぁ)
  • 数字タグに完全に対応していない。<NUMK VAL=132 COUNTER=enn>のような形式には未対応。数字+円とか数字+時とかだったらみたいにすれば対応可能かな。(追記:第二品詞に”助数詞”とはいるようなので、これを見ればいける気がする)


実装してみての気になる注意点


  • シリアル通信の場合、内部クロックでの動作の影響か、タイミングを取るのが結構シビア。
  • 可能ならI2Cのような別の手段で通信する方がいいとおもう。試してないけど。
  • PCの処理が高速でかつ、シリアルもマイコンにとっては十二分に早いので、適切に待つ必要がある。
  • BUSYが解除されてすぐにデータを送信しても、当然構文解釈するためにある程度の時間がかかるが、そのためのBUSYを返すまでの間に大量データを送信するとバッファが受けきれなくなる。
  • 一回の送信は100Byte程度に抑え、送信後BUSYにかかわらず1秒以上待つほうがいい。
  • BUSY信号は、何かしらの入力をしないと帰ってこない。又BUSY送信時、改行を送らないので、使用するライブラリによっては、ずっと受信中になる。(地味にハマった。)
  • 送信した音声記号中に解釈不可能な文字(記号など)が混ざっていると、送ったデータ全体が無効になる。記号直前まで喋ってくれたりはしない。
  • したがって、喋らないのは、解釈不可能な文字が混入しているか、バッファがOFしたかの判断がつかない。(一応長い文字列を送るとエラーコードを送るようになっているが、そもそもBUSYを発信する前にOFすると、どうやら解釈不可能としてエラーを出さず無効になるようです)

実装してみて、改めて日本語を読み上げるのが大変だと思い知った。
日本語を読み上げるだけでも、漢字、かなだけでなく、ローマ字読みもあれば時として英語読みもある。
MACはなぜエムエーシーではなくマックなのか。
ーはマイナス?ダッシュ?長音記号?
瞬時に文脈を判断し、適切な単語の区切りを見つけて、単語のよみを発声する。
しかもこれにアクセントやイントネーションまであるときたもんだ。
なかなか高度なことを普段やっている。




2011年8月2日火曜日

Rails3メモ

内容は随時追加変更
  1. ruby script/plugin installが使えない。
    例えば、こんなエラーが出る。
    ruby: No such file or directory -- script/plugin (LoadError)
    解決法:
    rails -hを見れば分かるが、コマンドが違う。正しくは以下のようにする。
    rails plugin install
  2. sh: svn: not foundがでる。
    解決法:
    subversionをインストールする。
    sudo apt-get install subversion
    (ubuntuの場合)
  3. Rails3でindex付きのコントローラを生成する。
    rails g controller コントローラ名 index
    (app/controllers/コントローラ名_controller.rbが作成される)
  4. Rails3で作成したコントローラ、モデルを削除する。
    rails destroy controller hoge
    rails destroy model fuga