ホーム ブログ ページ 56

surround.vim のつかいかた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

surround.vim のつかいかたです。Vim ライトユーザにもおすすめしたいので、にほんごで簡単につかいかたを書いてみます。

 導入

例により、vim.org から ダウンドードしてきます。

つい最近、バージョン 1.9 がでています。vim.org では Vim のバージョンが 6.0 対象と書かれていますが、ヘルプをみると Vim 7 以降がオススメとあるので、Vim 7以上でも安心です。

適当に展開して plugin, doc にファイルを置き、:helptags path/to/help(ヘルプの置いてあるパス) などとしてヘルプを引けるようにしておきます。

 テキストオブジェクトおさらい

surround.vim は vim のテキストオブジェクトに対する操作を拡張するプラグインです。テキストオブジェクトをざっくりおさらいです。

テキストオブジェクトはとてもおおざっぱに言えば、あるまとまりのテキストをのことです。このまとまりに対し操作を行なうことができます。

とりあえず見れば、ああ、あれか、と思うようなものなので、とりあえず見てみます。

# before

moji1    retu

というテキストがある場面で、moji1 のどこかの文字の上にノーマルモードでカーソルがあたっているとします。

そのときに diw とコマンド入力すると、”moji1″ というひとまとまりのテキストが削除されます(ここでは、単語という単位のひとまとまりのテキスト)。

# after

    retu

また、同じ場面で daw とすると “moji1 ” というひとまとまりのテキスト+次の単語までの空白文字が削除されます(ここでは単語と、それに付随している空白というまとまり)。

# after

retu

上で出てきた diw, daw のうちの、iw や、aw がテキストオブジェクトにあたります。diw の d は削除コマンド d のことで、テキストオブジェクト iw に対する操作コマンドになります。削除してインサートモードになる c や、ビジュアルモードの v などのコマンドが使えます。

テキストオブジェクトは iw, aw のほかにも以下のようなものがあります(見た目で、うごきがわかりやすいのをあげてみます。詳しくは :help text-objects)。

iw (単語)
aw (単語+次の文字までの空白)

it (タグの内部 <strong>hoge</strong> の hoge)
at (直近の外側にあるタグ含む文字列 <p><strong>hoge</strong></p> の場合、
    hoge や、strong 上でコマンドを入力すれば、<strong>hoge</strong> が対象になる)

i( (括弧内を以下略。 ib でも可。)
a( (括弧含め以下略。 ab でも可。 b は多分ブラケットの b です)

:h text-objects (ヘルプを見ましょう)

ということで、テキストオブジェクトはこんな感じのものでした。

 surround.vim について

surround.vim の基本的な概念

surround.vim での編集方法はざっくりで二種類の分けかたができます。

  1. 既に囲んでいるものに対する編集
  2. 新たにテキストオブジェクトを囲む編集
1. 既に囲んでいるものに対する編集

何かの記号やタグなどの、囲んでいるものに対して行なう編集です。そのまんまです。

ex:
'hoge'            (囲んでいるもの: ' )
"hoge"            (囲んでいるもの: " )
(hoge)            (囲んでいるもの: ())
<tag>hoge</tag>   (囲んでいるもの: <tag> )

[hoge]

{hoge}

といった文字列に対して利用できます。この「囲んでいるもの」たちを、削除したり、違うものに変えたりする、という操作ができます。

以下のコマンドの組みあわせで実現できます。

編集コマンド(d, c) + s(surround の s) + 囲んでるもの(‘ とか ” とか <tag> とか)

囲んでいるものを削除する場合は以下のようになります。

d + s + 囲んでるもの
ds'     (今カーソルのある文字列を囲んでいる ' を消す)
ds"     (" を)
ds(     (() を)
dst     (<tag> を)

囲んでいるものを変える場合は以下のようになります。

c + s + 囲んでるもの, + 変更したいもの
cs'"            (今囲んでいる ' を " に変える)
cs"<tag>        (今囲んでいる " を <tag> に変える)
cst<tag>        (直近で囲まれてるタグを <tag> に)
2. 新たにテキストオブジェクトを囲む編集

word に対する iw とかのテキストオブジェクトを、新たに囲む編集です。そのまんまです。

hoge
{ :foo => 'bar' }
he said, i am a pen.
hogehogehogehoge
yahhooooo konnichiha-

といった文字列を囲むという操作です。

以下のコマンドの組みあわせで実現できます。

ys + 範囲 + 囲む文字列

※ 以下では ‘*’ で、今カーソルのある位置を示し、||で囲まれた範囲はビジュアルモードで選択されているものとします。

befor                   →  after                     # コマンド

h*oge                   →  "hoge"                    # ysiw"
"↑ カーソル位置の単語を " で囲う

{ *:foo => 'bar' }      →  ( { :foo => 'bar' } )     # ysa{( or ysaBb
"↑ カーソル位置の {} で囲まれた文字列を () で囲う

he said, *i am a pen.   →  he said, "i am a pen."    # ys$"
"↑ カーソル位置がら行末までを " で囲う

hogehoge|hoge|hoge      →  hogehoge"hoge"hoge        # s"
"↑ 選択範囲を " で囲う

yahho*oooo konnichiha-  →  'yahhooooo konnichiha-'   # yss'
"↑ 行全体を ' で囲う。行指向操作。

以上が、surround.vim の機能、「既に囲んでいるものに対する編集」と「新たにテキストオブジェクトを囲む編集」です。

ほか

インサートモードでも使う

<C-G>s でインサートモードでも使えます。インサートモードで、以下のようなコマンドで操作します。

入力:
  <C-G>s<tag>
結果:
  <tag>*</tag> (* はカーソル位置。タグに囲まれた状態になる。)

入力:
  <C-G>s"
結果:
  "*"
自動でインデント(yS, S)

ys を yS に変えると囲うと同時にインデントもしてくれます。<div> などのタグで囲ったとき使うと少し便利かもしれません。

hello

という文字列のある行に対して、ySS<div> という操作をすると以下のようになります。

<div>
  hello
</div>
カスタマイズ

囲う文字列は自分で追加できます。vimrc とかに書いとくと使えるようになります。

let g:surround_コマンド = "開始 \r 終了"

let g:surround_45 = "<% \r %>"
"↑ 45 は - をコマンドに使うという意味。

let g:surround_61 = "<%= \r %>"
"↑ 61 は = のこと。この数値は、- とか = の上で :ascii すればわかります。

" 以下のように書くこともできます(直感的な書きかた)
let g:surround_{char2nr("-")} = "<% \r %>
let g:surround_{char2nr("=")} = "<%= \r %>

こう書いておくと、新たな – とか = の囲うコマンドが使えるようになります。

befor       →  after               # コマンド

'hoge'      →  <%= hoge %>         # cs'=
" ↑' で囲まれている文字列を <%=  %> で囲う

@hoge.name  →  <%= @hoge.name %>   # yss=
"↑ カーソルのある行を <%=  %> で囲う

ちなみに、上記の – とか = は、rails.vim + surround.vim という環境では、erb ファイルの編集時に使えるよう、はじめから定義されています。

もっとカスタマイズ

プロンプトでいろいろ尋ねながら入力した文字列を、囲うものの要素としてつかうことができます。

	let g:surround_{char2nr("d")} = "<div\1id: \r..*\r id=\"&\"\1>\r</div>"
	" hoge に ysiwd とかすると
	" id: というのが下のコマンドラインにでてくるので何かいれると
	" (たとえば main とか)
	" <div id="main">hoge</div>
	" というふうになります。
	
	let g:surround_{char2nr("a")} = "<a href=\"\r\">\1link_text: \r..*\r&\1</a>"
	" http://doruby.com という文字列に yssa などとすると、
	" link_text: などというプロンプトがでてくるので、何かいれると
	" (たとえば ナイスブログ とか)
	" <a href="http://doruby.com">ナイスブログ</a>
	" というふうになります。
	

プロンプトで尋ねるのは7つまで使えます。

もとからある t をツブすとタグを入力するとき残念なことになるので空いてる文字をさがして適当にわりあてましょう。

大変長くなってきました。長いのでもう終わりです。

快適 vim ライフをすごしましょう!

FireFox3.6のFileAPIを使ってドラッグ&ドロップでファイルアップロード

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


最近リリースされたFireFox 3.6ではFileAPIという機能が使えるようになりました。

今回はFileAPIで実現出来るようになったドラッグ&ドロップでのファイル選択を使ってファイルアップロード機能を実装してみます。

今回のスクリプトはこちらのサイトを参考に書きました。

Using files from web applications – MDC

ソースは以下のとおり。

<script language="javascript">
  function MultipartData(boundary) {
    this.boundary = boundary;
    this.data = "";
    this.data += "--" + boundary + "\r\n";

    this.append = function(name,value){
      this.data += "Content-Disposition: form-data; name=\"" + name + "\"\r\n\r\n";
      this.data += value + "\r\n";
    };

    this.appendFile = function(filename,filedata){
      this.data += "Content-Disposition: form-data; name=\"uploadfile\"; filename=\"" + filename +"\";\r\n";
      this.data += "Content-Type: application/octet-stream;\r\n\r\n";
      this.data += filedata + "\r\n";
    }

    this.appendBoundary = function(last){
      if(last != undefined && last == true){
        this.data += "--" + this.boundary + "--\r\n";
      } else {
        this.data += "--" + this.boundary + "\r\n";
      }
    }
  }

  function dragenter(e){
    e.stopPropagation();
    e.preventDefault();
  }

  function dragover(e){
    e.stopPropagation();
    e.preventDefault();
  }

  function drop(e){
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;
    this.files = files;
    var xhr = new XMLHttpRequest();
    boundary = "---------------------------14737809831466499882746641449";
    var multipartData = new MultipartData(boundary);

    multipartData.append("param","value");
    multipartData.appendBoundary();
    multipartData.append("multibyte_param",encodeURI("日本語"));
    multipartData.appendBoundary();
    multipartData.appendFile(encodeURI(files[0].name),files[0].getAsBinary());
    multipartData.appendBoundary(true);

    xhr.open("POST","/files/upload",true);
    xhr.onreadystatechange = function (aEvt) {
      if (xhr.readyState == 4) {
        if(xhr.status == 200){
          alert("アップロードが完了しました。");
        } else {
          alert("アップロードに失敗しました。");
        }
      }
    };
    xhr.setRequestHeader("Content-type","multipart/form-data; boundary="+boundary+ ";");
    xhr.setRequestHeader("Content-length",multipartData.data.length);
    xhr.sendAsBinary(multipartData.data);
  }

  document.getElementById("drop_area").addEventListener("dragenter",dragenter, false);
  document.getElementById("drop_area").addEventListener("dragover",dragover, false);
  document.getElementById("drop_area").addEventListener("drop",drop, false);
</script>

ドラッグ&ドロップでのファイル選択は以下のようにドロップイベントでイベントオブジェクトのdataTransferを取得するだけで簡単に実装できました。

    document.getElementById("drop_area").addEventListener("drop",drop, false);
  function drop(e){
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;
    this.files = files;

さて、あとは取得したファイルのデータをアップロードするだけなのですが、これがなかなか面倒です。ファイルと一緒に他のパラメタも送信したいので、データやバウンダリーなどを追加していけるオブジェクトを作ってmultipartなリクエストを自前で作ってポストしています。

一つ注意点としては、日本語をそのままパラメタに入れてsendAsBinaryで送信するとエラーが起きるので、適当にencodeURIでエンコードして送信しています。

というわけでファイルアップロード機能が実装できました。

受け手のサーバ側はRailsで作りましたが、PHPなどでもそのまま受け取れると思います。FileAPI便利ですね!

cameraOverlayView に触れる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちわ。iPhoneをもたないでiPhone開発するendです。
今日もちょっとiPhoneで遊んでみました。

UIImagePickerControllerが iPhone0S3.1 機能拡張された cameraOverlayView プロパティを利用して遊んでみました。
このcameraOverlayViewプロパティは、カメラを起動し表示される画面の上に、簡単に情報などを重ねて表示することができるものです。
拡張現実(AR)を作成するのに便利なものというところでしょうか。

今日は、ARというカッコよいものは作成できませんが、このcameraOverlayView に触れてみたいと思います。

 
    // UIImagePickerControllerのインスタンス化
    pickerController = [[UIImagePickerController alloc] init];
    // カメラモードの指定
    pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    // シャッターボタンなどを隠す
    pickerController.showsCameraControls = NO;
    // overlayViewは, UIViewに野菜の画像を複数 addSubView したもの。
    // それをcameraOverlayViewにセットする。
    pickerController.cameraOverlayView = overlayView;
    // UIImagePickerの表示
    [self presentModalViewController:pickerController animated:NO];

 あとは、NSTimerをつかって段々近づいてくる感じにゴニョゴニョにしてみました。

1
2
3

お。簡単!!

なぜ野菜なのかは特に理由はありません。

まだ発売されていないiPadを表示して、早くもiPadをゲットしたぜ!! なんて冗談をやろうとしたのだが、

やってみたら、あまり格好よくなかったので、野菜にしました。

PowerPointでのプレゼンテーションでのひと工夫

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

みなさま、こんにちはえーきち。。です。

みなさまPowerPointの”アニメーション”機能って使っていますか?

取り入れますと文字の羅列だった資料にメリハリが生まれ、

相手に伝えたいことを強調することができます。

ではそのいろいろ紹介していきましょう。。。

アニメーションには大きく2種類存在してます、

 (1)ページとページをまたぐ際のアニメーション

 (2)ページ内でのアニメーション

まずは(1)ページとページをまたぐ際のアニメーション、をいろいろ見ていきましょう。

ファイルをひらいてメニュータブの[アニメーション]を選択ください。

囲った部分が主にページとページをまたぐ際のアニメーションの設定になります。

 (A)アニメーションの種類

 (B)アニメーション切り替え時の音/速度

 (C)アニメーション切り替えのタイミング

になります。

(B),(C)に関しては名前のままの設定ですので細かくは省きますが

実際に使用した感じですと”画面切り替え時の速度”は”普通”もしくは”遅く”がいいかもしれません。

(A)のアニメーションの種類については、表示されている13種類(デフォルト+12種類)以外に

実は多数存在しているのはお気づきでしょうか?

(かくいう自分はけっこう最近まで気づいてませんでした)

(A)の右端にスクロールボタンが存在しています、これでさらに種類を選択することができ合計59種類(57種類+デフォルト+ランダム)バリエーションがあります。

この中から独断と偏見による使い勝手のよいものを3つをご紹介します。

 「時計回りの輪,4 スポーク」

 「スライドアウト右下へ」

 「サークル」

いずれも、ユーザーの視点があまりぶれずにアニメーションが行われているものです。

内容やページ内のアニメーションの有無にあわせて選択すべきですが

ひとつ選択したら同じアニメーションで通すほうが

ユーザーにとっては見やすいかもしれません。

いずれにしても何度も確認を行い作成してください。

次回は(2)ページ内でのアニメーションを説明させていただきます。

【Ruby】半角/全角バリデータ【Rails】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

入力項目には必ずといってもいいほど必要な「バリデーション」。
今回は、「その文字列が半角 or 全角文字のみであるか」というバリデーションをRubyで紹介します。今回の条件は以下の通りです。

半角文字:半角カタカナ、半角英数字、一部の記号(濁点、半濁点など)
全角文字:半角文字でないもの
メールアドレス、URLは除外

では、半角/全角のバリデーションのソース公開☆

KCODE = 'u'

  def self.hankaku?(str)
    return nil if str.nil?
    # 半角のみOKなので、全角が混ざっているとfalseが返る
    unless str.to_s =~ /^[ -~。-゚]*$/
      return false
    end
  return true
  end

  def self.zenkaku?(str)
    return nil if str.nil?
    # 全角のみOKなので、半角が混ざっているとfalseが返る
    unless str.to_s =~/^[^ -~。-゚]*$/
      return false
    end
    return true
  end

このままコピペすれば使えるはずです。
内容は非常に簡単で、正規表現で半角文字列にマッチするか否かを調べているだけです。

今回半角用と全角用を用意したのは、「その文字列が半角 or 全角文字だけで構成されているかどうか」を調べたかったからです。
hankakuメソッドだけでは、文字列が「全角文字と半角文字の混合」なのか「全角文字だけなのか」がわかりません。

では、住所のふりがなの入力チェックなんかに、ぜひ利用してみてください。

ブロックを使ったリファクタリング

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは、shimadaです。

今日は、Rubyの特徴の一つであるブロックを引数にとるメソッドの書き方を説明します。

題材として、「あちこちに同じ順番で処理が並んでいる時のコードの整理」を取り上げたいと思います。

重要な処理を行う場合に、開始、終了、エラーが起こったときの詳細を記録しなければならない。

そんな時の処理は、だいたいこんな風になるのではないでしょうか。

class SimpleWorker
  def action(arg)
    logger = Application.logger
    begin
      logger.info("SimpleWorker.action", "start")
      do_something
    rescue => e
      logger.error("SimpleWorker.action", e.message + e.backtrace.join("¥n"))
      logger.info("SimpleWorker.action", "abnormal end")
      raise
    else
      logger.info("SimpleWorker.action", "normal end")
    end
  end
end

class ComplexWorker
  def complex_action(arg1, arg2, arg3)
    logger = Application.logger
    begin
      logger.info("ComplexWorker.complex_action", "start")
      do_complex_thing1
      do_complex_thing2
      do_complex_thing3
      do_complex_thing4
      do_complex_thing5
    rescue => e
      logger.error("ComplexWorker.complex_action", e.message + e.backtrace.join("¥n"))
      logger.info("ComplexWorker.complex_action", "abnormal end")
      raise
    else
      logger.info("ComplexWorker.complex_action", "normal end")
    end
  end
end

同じような記述がたくさん並んでいてうんざりですね。

気になる点は2つあります。

  1. “SimpleWorker.action” という文字列が何度も出てきてうざい。
  2. begin .. rescue .. else .. end のパターンが似ているっていうか同じ

これをリファクタリングしてみましょう。合い言葉は「DRY」です。

1.は変数に入れてしまえばなんとかなりそうです。

2.については、「同じ処理の並びを共有する」というところからGoFで有名なテンプレートメソッドパターンとかを思いつきます。

でも、shimadaは継承が割と嫌いです。

「重要な処理」というのはシステムの色々なところにちょこちょこ出てくるので、「必ず同じ親クラスから派生していなければいけない」という制限をかけるのは、システムを設計する上で大きな足かせになりえるのです。

ではどうするか。Rubyの特色はmix-inです。そしてshimadaの好物は高階関数です。

手続きを引数にとる手続き、つまりブロックを受け取るメソッドをモジュールとして書いてみましょう。

module LogHandler
  def logging(task_name)
    logger = Application.logger
    begin
      logger.info(task_name, "start")
      yield(logger)
    rescue => e
      logger.error(task_name, e.message, e.backtrace.join("¥n"))
      logger.info(task_name, "abnormal end")
      raise
    else
      logger.info(task_name, "normal end")
    else
    end
  end
end

早速、各クラスにincludeして使ってみます。

class SimpleWorker
  include LogHandler
  def action(arg)
    logging("SimpleWorker.action") do |logger|
      do_something
    end
  end
end

class ComplexWorker
  include LogHandler
  def complex_action(arg1, arg2, arg3)
    logging("ComplexWorker.complex_action") do |logger|
      do_complex_thing1
      do_complex_thing2
      do_complex_thing3
      do_complex_thing4
      do_complex_thing5
    end
  end
end

すっきりしましたね。

また、ブロックを使ったプログラミングで混乱しがちなのが、「ブロックが受け取る引数」です。

この例ではyield(logger)に渡された値を do |logger| で受け取っています。

処理の流れが普通の関数呼び出しの逆になるので、初めての人は慣れるまでたくさん素振りして下さい。

ところでブロックを引数にとるメソッドの書き方には何種類かありますが、引数名に ‘&’ をつける方法は、受け取ったブロックを他のメソッドにそのまま渡したい時に便利です。

def method1(obj, &block)
  obj.method2(&block)
end

例を書くための例といった感じで、なにをしたいのかさっぱり不明ですが、実際のプロジェクトでまさにこういうコードが実際に必要になったというか先週書いたばかりです。プログラミングって不思議ですね!

ところで、振る舞いのリファクタリング以外でも、ブロック渡しは例えばテストを書くとき等にも役に立ちます。

shimadaがどんな風に使ったかは、また今度の機会に紹介したいと思います。

みなさんもブロックをどんどん使ってRubyを楽しんで下さい。

rails1.2.6の豆知識

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

リダイレクトとreturnについて

初めてrails1.xを使って、下記のfilterにちょっと詰まった。

———————————

before_filter :login_check

before_filter :load_data

def index

:

:

end

def login_check

 if session[:user].blank?

  redirect_to :action=>”index”

  return

 end

end

def load_data

 p “this is test”

end

——————————-

rails2.3の場合、動きは大丈夫ですが、今回は ログインしていない(session[:user] = nil)のに、indexページに遷移できず、 “this is test”が出力されていました。 確認すると、rails1.xの場合、確かに「return false」にしないと、リダイレクトしてくれません。

twitter4rであそぼう

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近プログラミングとか全然できてないハチネンです。さて、「私はやらない」と思っていた twitter ですが、 気がつけば「なんとなく」使ってしまってます。 少しプログラミングをしたくなったついでに twitter4r を使って遊びたいと思います。 まず、twitter4r をgemからインストールしてください。


% sudo gem install  twitter4r -r
Building native extensions.  This could take a while...
Successfully installed json-1.2.2
Successfully installed twitter4r-0.3.2
2 gems installed
Installing ri documentation for json-1.2.2...
Installing ri documentation for twitter4r-0.3.2...
Installing RDoc documentation for json-1.2.2...
Installing RDoc documentation for twitter4r-0.3.2...

自分のtwitterアカウントのログイン情報、パスワードを書いたYAMLファイルを一つ用意します。


myinfo:
  login: hachinen
  password: mypassword

上記の情報を使ってtwitterを操作してみましょう。感覚だけつかめればいいので、今回はirbから操作します。最初に必要なライブラリを読み込みます。


irb(main):002:0> require 'rubygems'
=> true
irb(main):003:0> require 'twitter'
=> true

最初に先ほどのYAMLを使って認証済みのオブジェクトを取得します。


irb(main):008:0> tw = Twitter::Client.from_config('./twit.yml','myinfo')
=> #

このオブジェクトを使ってまずは適当につぶやいてみます。


irb(main):009:0> tw.status(:post, 'おなかへったー(hetter)')
irb(main):011:0> tw.status(:post, 'おなかへったー')

きちんとPostできたでしょうか。ブラウザからも確認してみます。

うまくいったようです次はフォローしているユーザ一覧のスクリーン名を出してみます。


irb(main):012:0> tw.my(:friends).each {|f| puts "スクリーン名 = #{f.screen_name}" }
スクリーン名 = rails
スクリーン名 = slashdotjp
スクリーン名 = DoRuby

簡単ですね。次はタイムラインとかも出してみます。


irb(main):015:0> tw.timeline_for(:me).each {|tl| puts tl }
おなかへったー
おなかへったー(hetter)

ちゃんとでました。他にも http://twitter4r.rubyforge.org/rdoc/ を見てみると色々できるみたいなので、また遊んでみようと思います。

Nagiosでログ監視!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。wryyyです。

ディスク使用率や、Load Average等サーバに関する様々な監視が行える

Nagios

ですが、今回はNagiosでのログ監視について見て行きたいと思います。

まずは NagiosExchangeからcheck_logs.plをダウンロードし、インストールします。

(check_logs.plはperlで実行されるため、要perlです。)

そして、実行権を付けましょう!

これで、ひとまず ログ監視を実行できるようになりました。

さて、実行できたは良いものの

・どのファイルを読むのか

・どのエラーが発生した時に、メールを飛ばすようにするのか

等が設定できていないため、このままでは監視になりません。

ということで、次は「どのファイルを読み」、「どのエラーを拾うか」の設定をしていきます。

まずは、xxx.cfgというログ監視設定ファイルを作成し、/etc/nagios/check_logs/等、適当な場所へ配置します。

以下、設定ファイルの例です。

$seek_file_template='/var/lib/nagios/$log_file.check_log.seek';

# Required log files array
@log_files = (
      {'file_name' => '/var/log/syslog',
        'reg_exp' => '(ERROR|CRIT)',
     # 'lines' => 2,                #optional number of output lines  after match
     #  'new_line_reg_exp' => '^',  #optional new line regex to stop output lines
     #  'seek_file_suffix' => '2'   #optional seek file suffix
},
      {'file_name' => '/var/adm/messages',
       'reg_exp' => '(WARN|ERROR|FATAL)',
},
); 

上記、設定ファイルについて説明していきます。

まず、一番始めにある

$seek_file_template=’/var/tmp/$log_file.check_log.seek’;

これは、seekと呼ばれる、ログファイルを何行目まで読んだかを保存しておくファイルを指定しています。

次に、どのファイルを読むかについてですが、

これは、上部にある’file_name’ =>にて指定ができます。

次に、どのエラーを拾うかについては、

‘reg_exp’ => ‘(ERROR|CRIT)’を見てください。

()内に、拾いたい文言を「|」区切りで記載することにより、

()内に記載されている文言のログを拾う事ができます。

これで、基本的なログ監視の設定は以上です。

ただ、この設定だと拾わなくて良いログまで拾ってしまい、

このエラーは監視しなくて良いだろう!というログまで拾ってしまう可能性があります。

(su に失敗した時のエラーまで拾う必要はあるのか??等)

そこで、拾わなくて良いエラーがある場合は

‘neg_reg_exp’ => ‘()’

と記載することにより、()内に記載されているエラーは拾わないようになります。

以上、簡単ですがNagiosのログ監視設定でした。

監視に不必要なエラーを拾わないようにする設定は情報が少ないため、

参考にしていただけたら幸いです。

rubyでOAuthを使ってみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Google, twitter, mixiアプリなどのAPI認可のためのOAuth(オース)という

プロトコルが利用されています。

今回は、マッシュアップなWebサービスを作る上で必要になってくるOAuthの簡単な概念とrubyでの使用例を紹介したいと思います。

 OAuthとは?

デスクトップアプリやwebアプリケーションなどにセキュアなAPI認証の

標準的な手段を提供するオープンプロトコルです。

OAuth利用することによって、ユーザのgoogleアカウント情報(ID,Password)を保持しなくてもgoogleのアドレス帳などを参照するwebサービスを作ることができます。

 OAuthが必要になった背景

OAuthがなかった場合、先程の例のようなgoogleのアドレス帳を参照するサービスを作ろうとした場合、ユーザのgoogleアカウント情報をもとにアクセスすることになります。しかし、googleのアカウントはGmailやgoogleチェックアウトなど様々なサービスに紐づいており、迂闊にこのようなアクセスをすると万一の時のリスクが高くなります。

そもそもこの例では、googleのアドレス帳にさえアクセスできれば十分で、このように限られたリーソスへのアクセスを認証するため、APIへのアクセスを認可する手段が必要となりました。

 OAuthでのAPI認証の流れ

OAuthではトークンのやりとりによって、APIのアクセスの認可を行います。

OAuthではいかの登場人物が登場します。

  • OAuth Service Provider…APIを提供する側(例:twitter, google)
  • OAuth Service Consumer…APIを利用する側(例:twitterクライアント, google API群を利用したサービス)
  • User…ConsumerがProviderが提供するAPIを利用してProviderのサービスにアクセスすることを許可する人(例:twiiterクライアントを使おうとしている人)

それでは、OAuthによるAPIの認証の流れを説明します。

1) ConsumerはProviderにアプリケーションの登録を行い、Consumer KeyとConsumer Secretを取得する。

2) Consumer KeyとConsumer Secretをもとにrequestトークンを取得する

3) 取得したrequestトークンをもとに、ユーザがAPI認可するためのURLを生成する

4) ユーザは生成されたAPI認可のページアクセスし、ConsumerがAPIを利用してProvierにアクセスすること許可(または拒否)する

5) (以下許可されたと仮定)認可されたrequestトークンを元に、access token, access secretを取得する

6) access token, access secrete, consumer keyを元にAPIにアクセスする。

大まかにこんな流れでAPIの認証が行われます。改めてここで重要なのは「ConsumerにはユーザのProviderのアカウント情報がわたっていないことです」

大まかな流れが理解できたところで、実際にOAuthを使ってみたいと思います。今回は題名の通り ruby を使って twitter でのOAuthを試してみたいと思います。

 準備

あらかじめ、twitterのアプリ登録とoauthライブラリをインストールしておきます。rubyのoauthライブラリはgemでインストールできます。

gem install oauth

また、twitterのアクセスの簡単化のため twitterのライブラリもインストールしておきます

gem install twitter

 実際にやってみる

今回は、OAuthの流れをつかみやすくするためirbで試してみました。

require 'rubygems'
require 'oauth'

CONSUMER_KEY = "your-key"
CONSUMER_SECRET = "your-secret" 

consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com")

request_token = consumer.get_request_token 
# twitterに対してrequestトークンを要求

request_token.authorize_url # requrest tokenをもとに認証URLを生成

ここで表示されたURLにアクセスし、このrequest tokenを有効にしてください。

irbは止めずにこのままにしてください。

oauth_verifier = "000000" 
# 許可後した後に表示された数字を入力してください

access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier )
# 有効化されたrequest_tokenをもとにaccess token, access secretを取得

access_token = access_token.token
access_secret = access_token.secret

# access_key, access_secret, consumer_key, consumer_secretをもとにAPIにアクセスする
oauth = Twitter::OAuth.new(CONSUMER_KEY, CONSUMER_SECRET)
oauth.authorize_from_access(access_token, access_secret)
twitter_client = Twitter::Base.new(oauth)

# 投稿してみる
twitter_client.update("hogehoge")

ここで、実際に書き込まれたかtwitterに書き込まれたことを確認しましょう。無事書き込まれていたら、OAuthによるAPI認証成功です。

パスフレーズなしでSCP(秘密鍵の場合)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

パスフレーズなしでSCPをする方法としてはssh-agentを使う方法や、 秘密鍵を使う方法がありますが、今回は後者の秘密鍵を使う方法をご紹介します。

まず転送先のサーバで秘密鍵と公開鍵を作成します。
ここでポイントなのが秘密鍵はパスワードなしで作成するということ。
パスワードなしでも秘密鍵自体を盗まれなければ危険はありません。

(転送先での作業)
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_rsa):
Created directory ‘/home/hoge/.ssh’.
Enter passphrase (empty for no passphrase): (未入力でEnter)
Enter same passphrase again: (未入力でEnter)
Your identification has been saved in /home/hoge/.ssh/id_rsa.
Your public key has been saved in /home/hoge/.ssh/id_rsa.pub.
The key fingerprint is:
6e:f3:a4:af:aa:84:9f:d3:b2:92:84:69:34:10:21:b9 hoge@scp-to

次に作成した公開鍵(id_rsa.pub)を転送元に設定します。
※安全のため、公開鍵を設定するauthorized_keys2のパーミッションは、所有者に対しては read/write を許可し、他のユーザーには、アクセスを許可しないで下さい。

(転送元での作業)
$ vi ~/.ssh/authorized_keys2
### id_rsa.pubの内容をコピペ ###
ssh-rsa ****************************
$ chmod 600 ~/.ssh/authorized_keys2

これでパスフレーズなしでSCPができるはずです。
試してみます。

(転送元での作業)
$ echo “scp test” > /var/tmp/scp-test.txt
$ scp /var/tmp/scp-test.txt hoge@scp-to:/var/tmp
scp-test.txt 100% ****************************| 9 00:00

できました!

rubyでRSSを取得する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。T氏です。

今日はrubyでRSSを取得する方法をご紹介します。

rubyにはRSSを取得するためのクラスが用意されているため、それを使ったサンプル

を作成しました。

クラスは [RUBY_HOME]/rss/**.rb に色々と用意されています。

※rubyは1.8.7 を使っています。

# sample.rb
class Sample
  require 'rss'
  require 'uri'

  attr_accessor :title, :description, :link, :published_at

  def initialize
    @title = nil
    @description = nil
    @link = nil
    @published_at = nil
  end

  def self.get_rss(rss_url)
begin
      ary = []
      unless rss_url.nil?
        rss_results = ""
        url = URI.parse(rss_url).normalize
        open(url) do |http|
          response = http.read
          rss_results = RSS::Parser.parse(response, false)
          rss_results.items.each do |item|
            obj = self.new
            obj.title = item.title
            obj.description = item.description
            obj.link = item.link
            obj.published_at = item.date
            ary << obj
          end
        end
      end
      return ary
    rescue => e
      raise e
    end
  end

end

さて、実際に使ってみましょう。

ここではDoRuby!記事のRSSを取得しています。

$ irb -Ku
irb(main):001:0> require 'pp'
irb(main):002:0> require 'sample'
irb(main):003:0> rss = Sample.get_rss('http://doruby.kbmj.com/t_article/20091118/Rake_/feed')
irb(main):004:0> pp rss
[#   "こんにちは。T氏です。今日は自作のRakeタスクを追加する方法をご紹介します。 ",
  @link="http://doruby.kbmj.com/t_article/20091118/Rake_",
  @published_at=Wed Nov 18 10:00:00 +0900 2009,
  @title="Rakeタスクを追加する">,
 #  @description=
   "こんにちは。T氏です。 最近は、ようやくRailsの開発にも慣れてきました。慣れてくると、
Rails以外のフレームワークも使ってみたいな、なんて思ったりします。 そこで、以前から
気になっていたMerbのインストールから起動までをご紹介したいと思います。 \n",
  @link="http://doruby.kbmj.com/t_article/20090915/Merb_1",
  @published_at=Tue Sep 15 19:00:00 +0900 2009,
  @title="Merbを使ってみる">,
 #  @description=
   "こんにちは。T氏です。\n\n今日はRailsのエラー画面(public/404.htmlや500.html)への遷移は
どうやってされているかをご紹介します。",
  @link="http://doruby.kbmj.com/t_article/20090604/Rails_",
  @published_at=Thu Jun 04 19:47:37 +0900 2009,
  @title="Railsのエラー画面への処理を読む">,
 #  @description=
   "はじめまして!KBMJでエンジニアをやっているT氏です。初投稿の今回は、rakeコマンド
についてご紹介したいと思います。*rakeとは・・・ビルドツール(AntやMake等)のruby##の事    ",
  @link="http://doruby.kbmj.com/t_article/20090317/_rake_1",
  @published_at=Tue Mar 17 18:10:00 +0900 2009,
  @title=
   "Ruby on Railsでrakeコマンドを使って様々なタスクを実行しよう">]
irb(main):005:0> exit

無事に取得出来ましたね。

皆さんも試してみてはいかがでしょうか。

スマイリーメール

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。KBMJiの佐藤です。

今回はKBMJiで開発・販売しているiPhone向けのデコメアプリ「スマイリーメール」について紹介します。

スマイリーメール

http://farm5.static.flickr.com/4059/4349758775_654b4d722b_o.png
http://farm3.static.flickr.com/2614/4349758845_0984a8335e_o.png

スマイリーメールは、iPhone用のデコメアプリです。

スマイリーメールを使えば、iPhoneでデコメが使えるようになります。

アプリをインストールしたら、メールアドレスの設定を行います。

http://farm3.static.flickr.com/2724/4350505138_63621f151f_o.png

@i.softbank.jp で終わるメールアドレスからメールを送信する場合は、ここで「はい」ボタンをタップします。

http://farm3.static.flickr.com/2708/4350505192_9c3b114530_o.png

「SMTPサーバの設定」画面が表示されますので、ユーザ名とパスワードを入力します。

先ほどの「@i.softbank.jpで終わるメールアドレスから送信しますか?」とに対して「いいえ」ボタンをタップすると、

http://farm3.static.flickr.com/2801/4349759017_367afef946_o.png

「使用したいメールアドレスのSMTPサーバの情報が分かりますか?」と聞かれます。ここで「はい」ボタンをタップすると、

http://farm5.static.flickr.com/4002/4350505314_36cd1c4895_o.png

「SMTPサーバの設定」画面が表示されますので、メールアドレス・ホスト名・ユーザ名・パスワード・SSLを使用・サーバポートの入力を行い、「完了」ボタンをタップします。

先ほどの「使用したいメールアドレスのSMTPサーバの情報が分かりますか?」に対して「いいえ」ボタンをタップすると、

「メール送信」ボタンと「メールアドレス入力」ボタンが表示されます。

http://farm3.static.flickr.com/2487/4349759111_2f8e510429_o.png

ここで「メール送信」ボタンをタップすると、

空メールを送信することによってメールアドレスを登録することができます。

「メールアドレス入力」ボタンをタップすると、メールアドレスを手入力することによって登録することができます。

http://farm5.static.flickr.com/4025/4350505414_09e516707d_o.png

SMTP以外の方法でメールアドレスを登録すると、登録したアドレスに登録確認メールが届きますので、そのメール内に記載されている登録URLをタップして、本登録を行います。

http://farm3.static.flickr.com/2770/4349759227_9d5d73cdab_o.png

この画面がでれば登録完了!!

さっそくアプリを起動してください。

http://farm3.static.flickr.com/2704/4350505514_ef0e73d1d6_o.png

では、新規作成を選んで

http://farm5.static.flickr.com/4064/4350505566_c9cc8203f4_o.png

宛先をアドレス帳から選ぶ場合は[+]ボタンをタップ。

さていよいよ本文の編集です。本文の部分をタップすると

http://farm5.static.flickr.com/4041/4350505624_c5433edc0b_o.png

左から「文字の色変更」「文字の大きさ変更」「線を引く」「左・中・右寄せ」「アイコン・バナー画像選択」「背景色変更」「往復・スクロール」のアイコンが並んでいます。

アイコン・バナーは今後どんどん増やす予定なので、お楽しみに。

http://farm5.static.flickr.com/4009/4350505656_18af27eb85_o.png
http://farm5.static.flickr.com/4063/4349759405_1baea0499a_o.png
http://farm5.static.flickr.com/4020/4349759471_360f20b774_o.png
http://farm5.static.flickr.com/4039/4350505800_2ac830c731_o.png

さて色とりどりのメールができたら送ってみましょう。

http://farm5.static.flickr.com/4066/4349759569_0b9c0bc775_o.png
http://farm5.static.flickr.com/4008/4349759617_483266181b_o.png

ここで注意!相手に迷惑メールなどのフィルタで届かないことを防ぐ為に例えばあなたが@i.softbank.jpのアドレスを使っていたら相手に必ずドメイン指定受信の設定をしてもらってくださいね。

そうしないと届かないことがあります。サーバーを介してデコメを送っているので迷惑メールと間違えられる恐れがあるのです。。。

http://farm3.static.flickr.com/2449/4349759659_f936bc5fe4_o.png

署名などははじめからテンプレートにしてもよいかもですね。

http://farm5.static.flickr.com/4013/4350506016_9ae0da33f6_o.png

本文を編集中にテンプレートとして保存を押せばテンプレートとして保存できます。

署名はテンプレートにすることをオススメします!

http://farm5.static.flickr.com/4046/4350506062_8ba68d97ee_o.png

ここまで読んでくれた人に、裏技をこっそり教えます。

設定の項目に「日本国内モード」なるものがありますが、基本的に日本国内の方はオンにして欲しいのですが、オフにすると裏技が使えます。

送り先がiPhoneなどのスマートフォンかパソコンへのメールに限られますが【文字の大きさが12段階、画像の大きさも12段階に変更可能】にまずなります。

あとさらにiPhoneとパソコンに送る場合はフォントも4種類変えられます。

このあたりの機能は日本のデコメの仕様にはないので普通の日本の携帯には送れません。

http://farm3.static.flickr.com/2680/4350506152_51f03d0772_o.png
http://farm3.static.flickr.com/2794/4350506196_e7f906c3e1_o.png

どうですか?表現力が一段と増したと思いませんか?

友達に送って驚かせましょう!

http://farm3.static.flickr.com/2791/4349759967_3309ca4cfc_o.png
http://farm3.static.flickr.com/2487/4350506280_a8993008aa_o.png

まだまだいろいろと不明点や不満点があるかと思います。

質問や改善要望を support@kbmji.comまで、お気軽にお送りください。よろしくお願いします!

mod_jkを使ってtomcatとapacheの連携

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

tomcat-connector(mod_jk)を使用してみる
mod_jkとはTomcatとApache間の通信を処理するモジュールです。
色々設定方法はあるのですが今回は最も簡単な設定を行いapacehとtomcatの連携をしたいと思います。

環境は centos5.3 apacheはyumからインストールしました。

1: tomcatの起動

# cd /usr/local/src
# wget http://ftp.kddilabs.jp/infosystems/apache/tomcat/tomcat-5/v5.5.28/bin/apache-tomcat-5.5.28.tar.gz
# cd 任意の場所
# gunzip -c apache-tomcat-5.5.28.tar.gz | tar xvf –
# chown 起動ユーザ apache-tomcat-5.5.28
起動ユーザ% cd apache-tomcat-5.5.2/tomcat/bin
起動ユーザ% ./startup.sh

確認
http://localhost:8080/ tomcatの画面が表示されることを確認する


2:mod_jkのインストール


# cd /usr/local/src/
# wget http://www.meisei-u.ac.jp/mirror/apache/dist/tomcat/tomcat-connectors/jk/source/jk-1.2.28/tomcat-connectors-1.2.28-src.tar.gz
# gunzip -c tomcat-connectors-1.2.28-src.tar.gz |tar xvf –
# cd tomcat-connectors-1.2.28-src/native/
# ./configure –with-apxs=/usr/sbin/apxs
# make
# make install

すると下記のライブラリがインストールされます
/etc/httpd/modules/mod_jk.so


3:apacheの設定を行う

# cd /etc/httpd/conf
# vi httpd.conf

 LoadModule jk_module modules/mod_jk.so ライブラリを読み込む設定を追加

(同じようにライブラリを読み込みこんでいる設定があるので同じ場所に追加)

mod_jkの設定ファイルを読み込むための設定を追加(一番したなどでよい)

 Include /etc/httpd/conf/jk.conf 


# touch jk.conf
# vi jk.conf

 JkWorkersFile /etc/httpd/conf/workers.properties
 JkLogFile     /etc/httpd/logs/mod_jk.log   
 JkLogLevel    info
 JkShmFile     /var/run/apache2/jk-runtime-status
 JkMount /* jk


# touch workers.properties
# vi workers.properties

worker.list=jk
worker.jk.type=ajp13
worker.jk.host=localhost
worker.jk.port=8009
worker.jk.socket_timeout=5
worker.jk.connect_timeout=1000
worker.jk.prepost_timeout=1000

設定の説明
typeはapacheとtomcatの通信間のプロトコルを指します
portはtomcatの待ち受けportです 8009はtomcatのデフォルトの設定です

4:apache2の再起動と確認

# /etc/init.d/httpd restart

確認
http://localhost で上記tomcat起動で確認した

画面が表示されればOK

Grails(2)サンプルWEBアプリ作成~起動まで

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

次にサンプルWEBアプリを作成してみます。
(1)grails create-app test
 ※実行したディレクトリ内にtestディレクトリが作成されます。

(2)testディレクトリに移動します。

(3)grails run-app
 実行後、「Server running. Browse to http://localhost:8080/test」というのが表示されます。

(4)http://localhost:8080/test にブラウザからアクセスして下さい。
 ⇒Welcome to Grailsという画面が表示されれば成功です。
 ※「ctrl+C」で終了できます。

次回に続く・・・・。

Linuxの基本 ~コマンド編1~

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。エンジニア初心者のlietoです。

Linuxの基本的なコマンドの使い方についてまとめていきたいと思います。

今回は、「viコマンド」についてです。

viコマンド

 Linuxでテキストファイルを加工・編集するためのコマンドです。

【viの起動】

vi ファイル名

【文字の入力】

起動直後のviは、vi専用のコマンドを受け付けるコマンドモードという状態になっています。

文字入力を行うには、文字を入力するためのコマンドを使用します。

●文字入力の基本コマンド

 ・「i」:カーソルがある位置の左側から文字入力

 ・「a」:カーソルがある位置の右側から文字入力

●カーソルを移動しながら文字入力モードに移行する

 ・「I」:カーソルがある行の先頭から文字入力

 ・「A」:カーソルがある行の末尾から文字入力

●空行の挿入を行って文字入力モードに移行する

 ・「o」:カーソルがある行の次の行に空行を挿入し、その行の先頭から文字入力

 ・「O」:カーソルがある行に空行を挿入し、その行の先頭から文字入力

【カーソルの移動】

 ・「h」「←」:左へ移動

 ・「j」「↓」:下へ移動

 ・「k」「↑」:上へ移動

 ・「l」「→」:右へ移動

【ファイルの保存とviの終了】

●データの保存

 ・「:」「w」:上書き保存

 ・「:」「w」ファイル名:ファイル名をつけて保存

●viの終了

 ・「:」「q」:終了

 ・「:」「q」「!」:強制的に終了

 ・「:」「w」「q」または「Z」「Z」:保存して終了

【カット・コピー・ペースト】

●カット

 ・「x」:一文字カット

 ・「d」「d」:一行カット

●コピー

 ・「y」「y」:一行コピー

●ペースト

 ・「p」:カーソル位置のあとにペースト

 ・「P」:カーソル位置にペースト

【取り消しと繰り返し】

●取り消し

 ・「u」:直前の操作を取り消す(直前の状態に戻る)

●繰り返し

 ・「.」:直前の操作を繰り返す

【文字列の検索】

 ・「/」検索パターン:カーソル位置からファイルの末尾に向かって検索

 ・「?」検索パターン:カーソル位置からファイルの先頭に向かって検索

 ・「n」:次の検索結果へ進む

 ・「N」:前の検索結果へ進む

【文字列の置換】

 : 置換対象の行範囲 s/ 検索パターン / 置換文字列 / [オプション]

●置換対象の行範囲

 置換をする行は、「m行目からn行目」という範囲で指定しいます。

 実際には、「m,n」の形で記述します。

 例えば、「9行目から20行目」の場合、「9,20」となります。

 また、以下のような表現も利用できます。

 ・「.」:カーソルが存在する行

 ・「$」:最終行

 ・「%」:すべての行

●検索パターン

 基本正規表現を利用して検索できます。

●置換文字列

 置換したい文字列を記述します。

●オプション

 ・「c」:置換操作を実行する前に確認する

 ・「i」:大文字と小文字を区別しない

 ・「q」:一行の中に検索パターンにマッチする文字列が複数存在した場合、そのすべてに置換を適用

これで、viコマンドの基本は終了です。 

テキストファイルを自由に加工・編集できるようになりましたか?

それでは、また次回に。。

vim で アンドゥ、リドゥを含めたアンドゥ、リドゥ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

アンドゥは「元に戻す」、リドゥは「やり直し」のことですが、vimにもその機能は用意されています。 ・アンドゥ … u ・リドゥ  … Ctrl + r ですが、アンドゥやリドゥを繰り返している時に、うっかり履歴を消してしまう事が有ります。 こんな感じですね。1) 適当にタイプして… test1 test2 2) アンドゥして… test1 3) また適当にタイプすると… test1 test3 test2の履歴が消えてしまいました。 アンドゥしてもリドゥしても出てきません。 そこで、そんなときには、g- 、 g+ を使いましょう! アンドゥ、リドゥの履歴を含めたアンドゥやリドゥができますよ。

Rubyとメモリリーク

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ある日、mongrelプロセスのメモリ使用量を何となく見ていたところ、
同じ処理をしている他のサーバのものと明らかに違う数値を出していた。
これってもしかして、メモリリークってやつ?

言葉はよく聞くけど、自分自身があまりこれに悩まされた事がなかったため、
今回、ちゃんと正面から向き合う事にした。このメモリリークってやつに。

1. メモリリークとは?

今更だけど、要は使用可能なメモリ容量がどんどん減っていくこと。
アプリケーションが処理のために使ったメモリは、使い終わったら解放される
のが普通だけど、これが何らかの理由で解放されずに残ってしまう事を言う。
借りたものを返さない・・・・どこの世界にも不適な輩はいるらしい。

勘違いしがちなのは、メモリをいっぱい使うのとは直接関係ないという事。
一時的にメモリを大量消費する処理があったとしても、終わった後に解放
されるなら、それはメモリリークじゃない。
むしろ、メモリリークはもっと地味なものらしく、同じ処理が何千回も実行
されて初めて「なんか怪しくね?」って話になる事もざらだとか。

2. GC = Garbage Collecter

さて、メモリリークについて調べてたら、こんな単語に行き着いた。
GC。処理が終わった後、使われなくなったメモリを自動的に回収し、
メモリリークを起きにくくする機能。そういえば、昔読んだRubyの
入門書にも、そんな事書いてあった気がするなあ。

そんなのがあるんだったら、Rubyに関してはメモリリークを気にする
必要はないじゃん、と思ったんだけど、本当にそうなのか?
試しに「ruby」「メモリリーク」で検索かけてみる。
なんだよ、結構出てくるじゃん。

いろいろ調べてわかった事は、このGC。決して完璧なわけじゃない。
例えばメモリ上に、まだ使ってるのか使ってないのかわからないオブジェクト
があった場合、強気に解放してしまうGCと、弱気に様子を見るGCの二種類が
あって、Rubyの場合は後者を使用しているとの事。
だから、本当は参照されてないのに、いつまでも解放されず、結果的に
メモリリークになってしまう事があるのだと。

あと話は変わるけど、RubyのライブラリにはC言語で書かれているものが
あって、扱うオブジェクトの中にRubyのオブジェクトじゃないものがある
ために、それらがGCの対象にならず、メモリーリークの要因になる可能性
もあるんだとか。

ただ、こういうのはすぐに報告されて、バージョンアップで修正されてる
みたいだから、バージョンに気を付けて使っていれば問題ないんじゃないか
と思う。

3. で、結局、冒頭の話はメモリリークだったのか?

わからん。
とりあえずmongrelを再起動したら(当たり前だけど)元に戻ったので、
しばらく様子見かなあ。
メモリリークの原因を追及するのと、定期的にmongrelを再起動するの
だったら、後者の方が楽だしなあ。
まあ、あとは常駐プロセスじゃないpassengerとか、近頃噂のunicornとやらを
試してみるのも手か。

最後に。Rubyのメモリリーク検出ツールなるものを見つけました。
英語マニュアルしかなかったので、自分はわかった風なところまでしか
行きませんでしたが、良かったらチャレンジしてみてください。

<Ruby用メモリリーク検出ツール「Bleak_house」>【動作環境】
 UNIX系OS
 Ruby1.8.7

【インストール】
 $ gem install bleak_house

【セットアップ】
 config/environment.rbに以下の1行を追加。
  require ‘bleak_house’ if ENV[‘BLEAK_HOUSE’]

【使い方】
 1. アプリケーションサーバを起動
  $ RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house ./script/server
 2. 200〜300リクエストを投げたところで、サーバを停止(Ctrl-C)。
 3. /tmp以下にダンプファイルが出来ているので、その内容を解析。
  $ bleak /tmp/bleak.20349.000.dump

【参考URL】
 http://blog.evanweaver.com/files/doc/fauna/bleak_house/files/README.html

Ruby on Rails でモデルを階層化する(サブディレクトリにモデルを入れる)方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

通常、モデルのファイルはmodelsディレクトリの直下にファイルを作成しますが、管理の都合など何らかの理由でモデルをサブディレクトリに入れたいことがあると思います。

例:models/sample/category.rb

module Sample
  class Category < ActiveRecord::Base
    set_table_name “sample_categories”
  end
end

モデルを階層化する(サブディレクトリにモデルを入れる)方法として、environment.rbでconfig.load_paths にサブディレクトリのモデルを追加する方法が色々なブログで紹介されています。

http://errtheblog.com/posts/3-organize-your-modelshttp://toolmantim.com/articles/keeping_models_in_subdirectorieshttp://www.kevinmonk.co.uk/?p=38

config.load_paths += Dir[“#{RAILS_ROOT}/app/models/**/**”]

しかし上記方法で問題が出る場合もあり、さらに簡単な方法で実現できますのでご紹介します。

サブディレクトリ内のモデルをコントローラ内で利用する際に、::Sample::Category (Sample::Category ではない!) という風に呼び出すことで config.load_paths の追加等をせずに利用することができます。
Sample::Categoryで呼び出した場合に問題が出る場合がありますので、::Sample::Categoryと先頭に「::」を付けて呼び出すことで問題が直る場合がありますのでお試しください。

Webroar を Macports の Ruby で動かすでござる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

エレコマの開発を担当しているたろちゃんです。

Webroarは以前Daoka氏が紹介をしていたが、Macportsで導入したRubyの上で動作しませんでした。また、SSLのサポートも通らなかったため、両方が動くように調整をしてみました。

今回はSSL環境を構築したいため、gnutlsを導入します。

$ sudo port install gnutls

webroarの導入自体は以下のコマンドで行ないました。

$ sudo gem install webroar

ユーザガイドに沿ってインストールを行なうと以下のようにエラーとなりました。

wisp:~ btm$ sudo webroar install --ssl-support
Checking for the dependencies ...
Checking for ruby........found   at /opt/local/bin/ruby.
Checking for libruby.1.8.7.dylib........found  at /opt/local/lib.
Checking for openssl-ruby........found.
Checking for zlib-ruby........found.
Checking for ruby_headers........found   at /opt/local/lib/ruby/1.8/i686-darwin10/ruby.h.
Checking for rubygems........found.
Checking for /usr/bin/gcc-4.2........found   at /usr/bin/gcc-4.2.
Checking for make........found   at /usr/bin/make.
Checking for starling........found   at /opt/local/bin/starling.
Checking for Xcode.app........found   at /Developer/Applications/Xcode.app.
Checking for any previous installation of WebROaR ... found.

Please enter your choice from the options below:
 1. Import configuration, logs and admin panel data from the previous installation - WebROaR-0.2.6.
 2. No import required, install WebROaR-0.2.6 afresh.
> 1
Importing configuration, logs and admin panel data from the previous WebROaR-0.2.6 install ... done.
Creating directory structure ... done.
Compiling C source files ... failed.
Compilation error. Please refer 'install.log' for details.

install.logは /opt/local/lib/ruby/gems/1.8/gems/webroar-0.2.6/install.log に置かれます。それを見ると gnutls.h が見つからないというメッセージが出ていました。これは単純に -I/opt/local/include と -L/opt/local/lib をコンパイル時に渡せば良いという事ですが、実は gnutls に依存している webroar-head だけではなく、webroar-worker も -L/opt/local/lib を渡さなければならない事が後々判明しました。これは、ライブラリのパスを渡さないと MacOSX に付属している Ruby のライブラリを参照してしまうからです。

$ otool -L /opt/local/lib/ruby/gems/1.8/gems/webroar-0.2.6/bin/webroar-worker 
/opt/local/lib/ruby/gems/1.8/gems/webroar-0.2.6/bin/webroar-worker:
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
	/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/libruby.1.dylib (compatibility version 1.8.0, current version 1.8.7)

このため、両方のリンク時に必ず -L/opt/local/lib を指定するようにしなくてはなりません。

今回はwebroar 0.2.6 を対象に次のようなパッチを用意しました。

--- lib/command_runner.rb.orig	2010-01-19 17:37:20.000000000 +0900
+++ lib/command_runner.rb	2010-01-19 17:36:53.000000000 +0900
@@ -56,6 +56,7 @@
   Options:
     -s, --ssl-support      Install the server with SSL support
     -d, --debug-build      Compile the server as a debug build to output extremely verbose logs 
+    -m, --macports         Compile the server with MacPorts Ruby
 
   Summary:
     Install the server
@@ -175,6 +176,10 @@
       options[:report_dir] = dir
     end
 
+    opts.on( '-m', '--macports', 'Compile with MacPorts Ruby') do
+      options[:macports] = true
+    end
+
   end
 
   begin
--- lib/installer.rb.orig	2010-01-19 17:38:03.000000000 +0900
+++ lib/installer.rb	2010-01-19 18:11:26.000000000 +0900
@@ -165,7 +165,11 @@
       ssl = true
       str = "ssl=yes "
     end
-    
+   
+    if options[:macports]
+      str += "macports=yes "
+    end
+
     if CheckUser.new.check == 0
       
 #      if File.exist?(File.join(WEBROAR_BIN_DIR,"webroar-head")) && File.exist?(File.join(WEBROAR_BIN_DIR,"webroar-worker"))
--- tasks/compile.rake.orig	2010-01-19 11:54:46.000000000 +0900
+++ tasks/compile.rake	2010-01-19 17:43:29.000000000 +0900
@@ -66,6 +66,9 @@
     puts "Adding HAVE_GNUTLS flag."
     $flags << '-DHAVE_GNUTLS'
   end
+  if ENV['macports'].eql?("yes")
+    puts "Building for MacPorts Ruby build."
+  end
   $flags = $flags.join(" ")
   $webroar_config_called=true
 end
@@ -128,12 +131,18 @@
 TEST_OBJ_DIR = File.join(OBJ_DIR, 'test').freeze
 LOG_FILES = File.join('','var','log','webroar').freeze
 TMP_FILES = File.join('','tmp').freeze
+MACPORTS_HEADER_DIR = File.join('', 'opt', 'local', 'include').freeze
+MACPORTS_LIB_DIR = File.join('', 'opt', 'local', 'lib').freeze
 
 ## Create necessory directories
 #create_directories([OBJ_DIR, WORKER_OBJ_DIR, YAML_OBJ_DIR, TEST_OBJ_DIR, TMP_FILES, LOG_FILES])
 
 include_dir = ["#{LIBEV_DIR}","#{EBB_DIR}","#{HEAD_DIR}","#{YAML_DIR}","#{HELPER_DIR}","#{UNIT_TEST_DIR}", "#{WORKER_DIR}"]
 
+if ENV['macports'].eql?("yes")
+  include_dir << "#{MACPORTS_HEADER_DIR}"
+end
+
 include_dir.each do |dir|
   $inc_flags << " -I#{dir} "
 end
@@ -244,6 +253,10 @@
   $libs += $LIBS + ' ' + Config::expand($LIBRUBYARG_SHARED,CONFIG)
   #$libs += ' '+CONFIG["LIBRUBYARG"]  
   $libs += ' -lpthread '
+  if ENV['macports'].eql?("yes")
+    puts "Compiling with MacPorts Ruby."
+    $libs += " -L#{MACPORTS_LIB_DIR} "
+  end
   out_file=File.join(BIN_DIR,'webroar-worker')
   object_files=FileList[File.join(WORKER_OBJ_DIR,'*.o'), helper_obj.keys, File.join(YAML_OBJ_DIR,'*.o')]
   # -rdynamic option to get function name in stacktrace
@@ -263,6 +276,10 @@
     puts "Compiling with gnutls library."
     $libs += ' -lgnutls '
   end
+  if ENV['macports'].eql?("yes")
+    puts "Compiling with MacPorts Ruby."
+    $libs += " -L#{MACPORTS_LIB_DIR} "
+  end
   out_file=File.join(BIN_DIR,'webroar-head')
   object_files=FileList[File.join(OBJ_DIR,'*.o'),File.join(YAML_OBJ_DIR,'*.o')]
   # -rdynamic option to get function name in stacktrace
--- tasks/gem.rake.orig	2010-01-19 17:54:13.000000000 +0900
+++ tasks/gem.rake	2010-01-19 17:54:39.000000000 +0900
@@ -118,7 +118,11 @@
   if ENV['debug_build'] == 'yes'
     opt_str += "-d "
   end 
-  
+ 
+  if ENV['macports'] == 'yes'
+    opt_str += "-m "
+  end
+
   sh "webroar install #{opt_str}" 
 end
 

パッチの内容は webroar install にオプション -m もしくは –macports を追加してMacPorts用にビルドをしたい場合はオプションを付けるようにするというものです。

これをwebroar_0.2.6_macports_patch.diffとして適当なディレクトリに用意します。

では、パッチを当ててビルドをしてみましょう。

$ cd /opt/local/lib/ruby/gems/1.8/gems/webroar-0.2.6
$ sudo patch -p 0 < ~/develop/ruby/webroar_0.2.6_macports_patch.diff
$ sudo webroar install -s -m

正常に動作するでしょうか?Admin Panelにログインができたら、後は指示に従って導入を進める事ができます。

なお、筆者のケースで、rack-1.1.0が入ってしまい上手く動作させる事ができない事がありました。これはrails-2.3.5がrack-1.0.1に依存(正確にはrailsが依存してるライブラリが依存)しているためです。しかし、このようなケースだとログに一部出力されずに分かりづらい事があります。そういう時はwebroarをdebugオプションつきでインストールをして、/var/log/webroar 以下のファイルを確認するようにしましょう。

HTML5入門

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

※この記事は 2010.01.18 時点のものです。現在の内容とは異なる内容が含まれている場合がございますので、ご注意ください。

こんにちは。エンジニアの はる です。

今回は巷で話題の「HTML5」について、

 ・HTML5とは?
・HTML5って何が変わるの?
・HTML5っていつから気にしなきゃいけないの?

という視点から、まずはHTML5をざっくりと知っていただくための入門的な内容を書いてみたいと思います。



・HTML5とは?

W3Cより2008年1月22日にドラフト(草案)が発表されたHTMLの最新バージョン。※2010年9月頃に正式版勧告予定。
HTML4と比べ、WEBアプリケーション向けの機能が大幅に強化されており、また、HTML4.01で非推奨とされていた要素の一部(font要素やcenter要素等)が廃止されてる予定です。
主な追加機能としては、

■新しい要素や属性の追加
(1)入力フォームの強化
(2)canvas要素
(3)文書構造を示す要素の追加(header要素、nav要素 等)
(4)その他(menu要素、command要素 等)


■新しいAPI
(1)簡易データベース(Web Storage)
(2)マルチスレッド(Web Workers)
(3)双方向通信(Web Sockets)
(4)その他(アプリケーションキャッシュ、ドラッグ&ドロップ等)


上記が主要な追加機能となります。その他にも多くの機能追加があるのですが、今回は割愛させていただきます。
それでは、次項にて具体的な各機能の内容をご紹介します。

———————————————————–

・HTML5って何が変わるの?


■新しい要素や属性の追加


(1)入力フォームの強化

□type属性に指定できる型が増える
HTML5からは、input要素のtype属性に指定できる型が増えます。
search、datetime、date、month、number、range、tel、email 等…計23種類になる見込みです。
例えば、「date」型では、date型の入力フォームをクリックするとカレンダーが表示され、そのカレンダーから日付を選択するインターフェイス(※Operaで確認できます。)がブラウザで実装され、
、「range」型では、スライダーコントロールが表示され、感覚でスライダーを動かして入力するインターフェイス(※Safariで確認できます。)がブラウザで実装されます。

例)

HTML5入門
HTML5入門
HTML5入門
HTML5入門

このように今までAjaxやFlashで実装されていたUIがHTMLの標準機能として実装可能になり、type属性の指定型が増えたことで入力項目の型をソースレベルで明確化することができます。

range型を携帯で入力する場合は左右ボタンは使えないし、どうするんだろう・・・といった不安はあるものの、優れたUIをエンドユーザーが利用できる機会が多くなるのは嬉しいですね。



□フォームの値を検証する属性が追加
これまでJavascriptで実装されてきたフォームの値の検証もHTMLの標準機能として、ある程度行えるようになります。
具体的には、必須項目のチェックと正規表現によるフォーマットチェックとなり、submitボタンを押した際にチェックが行われます。
不正値が発見された場合には不正値が入力されている項目が赤く表示され、メッセージが表示されます。(※Operaで確認できます。)

例)
必須項目のチェック(required属性)

フォーマットチェック※正規表現で指定(pattern属性)


(2)canvas要素
canvas要素は、HTML(+CSS3)で自由にグラフィックの描画(2D,3D)、写真合成、アニメーションの作成等を可能にする要素です。
canvas要素については、説明するよりも実際に見てみたほうが分かりやすいかと思いますので、いくつか参考になるサイトをご紹介します。


□Canvas参考サイト

  • ・canvas要素 + css3アニメーション

http://www.agustinfernandez.com.ar/proyectos/canvas/

  • ・canvas要素 + audio要素

http://9elements.com/io/projects/html5/canvas/

  • ・canvas要素 + jQuery

http://www.filamentgroup.com/lab/jquery_visualize_plugin_accessible_charts_graphs_from_tables_html5_canvas/


HTML5+CSS3+javascriptでゲーム等も作成可能とされていますが、現状では、3D、アニメーション、テクスチャのレンダリングが重く感じてしまいます。
canvas要素を利用することにより、AjaxやFlash、Silverlightで実装されていたリッチコンテンツをHTML5でより容易に実装可能になります。
Flash Developerとしては、Flashとの機能的な違いや両者の棲み分けがどうなされるのかという点が気になるところではありますが、リッチコンテンツ制作の間口が広がることでインターネットコンテンツの幅も広がるといいなと思います。

(3)文書構造を示す要素の追加(header要素、nav要素 等)
header要素、footer要素、nav要素、article要素等…HTMLの文書構造を明確に示すための要素が追加されます。
文書構造が明確になることにより、検索エンジンのインデックス化処理(検索ページの索引作り)が容易になります。
※現時点では、検索エンジンのインデックス化処理が容易になるというだけであって、HTML5にすることで直接的なSEO効果があるわけではないようです。

(4)その他(menu要素、command要素 等)
その他にも、menu要素、command要素、progress要素、meter要素等々…ここでは紹介しきれない程の新要素や、HTML4の時には用途が変わって実装されている要素があります。
興味のある型は是非調べてみてください。



■新しいAPI


(1)簡易データベース(Web Storage)

クライアント端末内にデータを保存するためのAPIが提供されます。簡易データベースの種類には「キー/バリュー」形式のものとデータベース形式(※Safariの場合SQLiteを使用しているようです。)(※Safariの場合、バックエンドではSQLiteを使用しているようです。)のものの2種類があります。

  • Storage

キー/バリュー形式で保存
ドメイン毎の保存(永続可能)、ウィンドウ毎の保存(ウィンドウを閉じるまで)が可能

  • データベース

SQLを用いて保存(※トランザクション必須)
非同期APIと同期APIでのアクセスが可能(永続可能)


簡易データベースを活用することで、今まで逐一サーバーと通信をして保存していたデータを必要な時のみ適宜通信をして保存したり、オフラインで編集したものをオンライン時にサーバー側に保存する等、様々な使い道がありそうです。

□参考サイト(※Safari、Chromeでご覧ください)

  • WEB Storage + オフライン作業(manifest)

http://webkit.org/demos/calendar/Calendar.html


(2)マルチスレッド(Web Workers)
バックグラウンドで動作するjavascriptスレッドのことで、これまでは計算処理を行うjavascriptがあった場合に、その処理が完了するまでUI側の操作が一時的に行えない状態になる等の影響がありましたが、
Web Workersを使用することで、例えば計算処理をワーカに渡し、UI側は計算処理中でも操作可能にするといったことも可能となります。
また、Web Wokersは、複数立ち上げることが可能(マルチスレッド)であり、postMessageを使用することで、Worker間、Workerと表示側のjavascript間等で処理結果の受け渡しや協調が可能です。
ただし、Web WorkersはDOMにアクセスできないので、注意が必要です。

(3)双方向通信(Web Sockets)
サーバーサイドプロセスとの双方向通信を可能にするAPIであり、HTTPを使用せずに効率的な双方向通信が可能となります。
HTTPヘッダやCookie情報が含まれない通信のため、トラフィックを軽減できます。

(4)その他(アプリケーションキャッシュ、ドラッグ&ドロップ等)

その他にも、アプリケーションキャッシュ(manifest)、ドラッグ&ドロップ機能等の新しいAPIがあります。興味のある型は是非調べてみてください。

 ———————————————————–

・HTML5っていつから気にしなきゃいけないの?

HTML5がどんなに話題になってもエンドユーザーが満足に利用できる環境がなくては普及はしません。
つまり、利用者側がいつから満足に使用できるかが開発者側の対応が必要になるタイミングでもあるわけですが、これはHTML5に対応したブラウザのシェアによるかと思います。
各ブラウザの対応状況は、下記サイトで確認することができます。


上記サイトで各ブラウザの対応状況をみてみると、webkitベースのブラウザ(Safari、Chrome)はかなりの対応率ですが、IEの対応状況が芳しくありません。今後の対応予定もしばらくは期待できなそうですね。
Operaは現在はまだまだといった結果ではありますが、本格的にHTML5対応を宣言しているので今後に期待です。
正直なところ、PCのブラウザが未だIEが高いシェアを保っているため、しばらくは普及が見込めなそうです。
ただし、ブラウザの入れ替わりが比較的早い携帯電話では昨今のスマートフォンブームと相まって、PC版よりも早く標準になる可能性はあるのではないでしょうか。

今回ご紹介したHTML5についての記事は、HTML5の中のほんの一部の内容です。興味のある方は是非調べてみてはいかがでしょうか。

□その他の参考にさせていただいたサイト

  • 5分で把握するHTML5 – Google Developer Dayセッションリポート

http://journal.mycom.co.jp/articles/2009/06/15/gdd1/index.html

  • 詳解! HTML 5と関連APIの最新動向 – 新タグ&API編

http://journal.mycom.co.jp/special/2009/html5-1/index.html

  • 詳解! HTML 5と関連APIの最新動向 – Webアプリ開発編

http://journal.mycom.co.jp/special/2009/html5-2/index.html

  • HTML5リファレンス

http://www.html5.jp/

最近人気な記事