全行のインデントを揃える

ずーっと知りたかったのだけど、
ずーっと分からなかったことがやっと分かった。
以下のコマンドで、バッファに読み込んでいる全ての行の
インデントを揃えることができる。
超便利っ!

M-x mark-whole-buffer
M-x indent-region

あとはこれをキーバインドに対応付ければもっと便利になりそう。

追記

コメントから、僕の探しているバインドは既にあることを教えてもらった。

M-x make-command-summary

とやると、コマンドとバインドの対応表のようなものが出てきたので、
そこを探したら見つかった。

  • C-x h ・・・ mark-whole-buffer
  • C-M-¥ ・・・ indent-region

よし!これでバッチリだ!
と思ったのだけど、
そういえば C-M ってどうやって入力すればいいんだろう?
またまた基本的なところで躓いてしまった・・・。

追記

結局 C-M と入力する方法が分からないままなので、
indent-region に M-I を割り当てることにした。
M-I を indent-region に割り当て - gan2 の Ruby 勉強日記


その後、C-I にもっと強力なのを割り当てることにした。
バッファ全体を untabify と indent する - gan2 の Ruby 勉強日記

正規表現でマッチした箇所と、その前後を取り出す

Regexp#matchを使うと、MatchDataオブジェクトが返される。
そしてMatchDataを使えば、マッチした結果の詳細を見ることができる。

  • MatchData#[n] ・・・ n番目にマッチした部分の文字列
  • MatchData#pre_match ・・・ マッチした部分より前の文字列
  • MatchData#post_match ・・・ マッチした部分より後の文字列

例えば、$を含む文字列にマッチした結果を見てみると以下のようになる。

ary = [
       'Hoge$1.class',
       'Hoge$Fuga.class',
       'Hoge$Fuga$Piyo.class',
      ]

ary.each{|item|
  if m = /\$/.match(item)
    puts "target: #{item}"
    puts "pre_match: #{m.pre_match}"
    puts "match: #{m[0]}"
    puts "post_match: #{m.post_match}"
    puts 
  end
}


実行結果。
これで、正規表現を適用した結果が、
自分の意図したものになっているかどうかが調べられる。

target: Hoge$1.class
pre_match: Hoge
match: $
post_match: 1.class

target: Hoge$Fuga.class
pre_match: Hoge
match: $
post_match: Fuga.class

target: Hoge$Fuga$Piyo.class
pre_match: Hoge
match: $
post_match: Fuga$Piyo.class

Ajaxなチャットを作ってみた

サンプルはここ→http://www.gan2.65rpm.com/lab/ajax-chat.html
デザインは全然何もいじってない。
とりあえず、これから色々作っていくものの雛形って感じ。
ファイルは、HTMLとJavaScriptCGIスクリプト(Ruby)の3つに分けてある。
JavaScriptのライブラリはprototype.jsを使用。
以下はソース。

ajax-chat.html
<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Ajaxなチャット</title>
    <script type="text/javascript" src="lib/prototype.js"></script>
    <script type="text/javascript" src="ajax-chat.js"></script>
  </head>
  <body>
    <h1>Ajaxなチャット</h1>
    <form method="get" id="form" onsubmit="saveData(); return false;">
      <input type="text" id="name" value="名前" size="16" />
      <input type="text" id="text" value="ここに書き込んで!" size="64" />
      <input type="submit" value="保存"><br />
    </form>
    <div id="result"></div>
  </body>
</html>

prototype.jsには、
入力フォームの値を参照する便利なショートカット$F()があるのだけど、
これは、$F('id')のように id を指定してやらなくちゃいけない。
最初、inputタグには id を書いてなくて、変わりに name を書いていた。
それで何でこれで動かないんだろうとしばらく悩んだ。
単純なミスだけど、prototype.jsを使うときは、
name じゃなくて id を使うように、普段から心がけておいた方がよさそうだ。

ajax-chat.js
function saveData(){
    var name = $F('name');
    var text = $F('text');
    text = text.replace(/&/g, "&");

    var url = 'ajax-chat.cgi';
    var pars = 'name=' + name + '&text=' + text;

    var myAjax = new Ajax.Request(
				  url,
				  {
				      method: 'get',
				      parameters: pars,
				      onComplete: showResult
				  });
}

function showResult(originalRequest){
    $('result').innerHTML = originalRequest.responseText;
    $('text').value = '';
}

Ajax.Requestをnewしているところのインデントがちょっと気に入らない。
javascript.elを使っているんだけど、これはちょっと凹み過ぎな気がします!
最後の方にある $('text').value = ''; で、
フォームのテキストフィールドが空にすることができる。

ajax-chat.cgi
#!/usr/local/bin/ruby
require 'cgi'
require 'kconv'
print "Content-Type: text/html\n\n"

class BBS
  def initialize(log_filename = 'ajax-chat.log')
    @cgi = CGI.new
    @log_filename = log_filename
    @MAX_LOG = 20
    @log = []
  end
  
  # ログファイルの読み込み
  def read_log_file
    open(@log_filename){|f|
      f.each{|l|
        @log << l.toutf8
        break if @log.size == @MAX_LOG
      }
    }
  end

  # ログファイルへの書き込み
  def write_log_file
    name = @cgi['name'].toutf8
    text = @cgi['text'].toutf8
    return unless name.size > 0 or text.size > 0
    time = Time.now.strftime("%Y/%m/%d-%X")
    
    @log.unshift "#{time}  [#{name}] #{lf2br(text)}<br />"
    
    open(@log_filename, 'w'){|f|
      c = 0
      @log.each{|l|
        l.chomp!
        f.puts lf2br(l)
        c += 1
        break if c == @MAX_LOG
      }
    }
  end

  def lf2br(str)
    str.gsub!(/\r\n/, '<br />')
    str.gsub!(/\r/, '<br />')
    str.gsub!(/\n/, '<br />')

    str
  end

  def output_result
    @log.each{|l|
      puts l
    }
  end
end


log_filename = 'ajax-chat.log'
bbs = BBS.new(log_filename)

bbs.read_log_file
bbs.write_log_file
bbs.output_result

Ajaxなチャットと言っておきながら、RubyのクラスはBBSだったりする。
でもログを読んだり書いたりする部分は、
チャットでも掲示板でも同じだと思うので、名前については特に気にしない。


この3つのファイル以外に、
空っぽの ajax-chat.log ファイルと、
lib フォルダ以下に prototype.js を用意し、
CGIの実行権限を755にしてやれば、Rubyの動くサーバならどこでも動くと思う。
あ、あとshebang(#!から始まる一行目)も変更が必要かもしれない。

あわせて読みたい | 読者が読んでいる話題の記事をオススメ

screenshot

あわせて読みたい」とは、あなたのブログ読者が「よく読んでいる」ブログを知ることができる無料サービスです。

あわせて読みたい」をブログに貼り付けることで、あなたのブログ読者が「あわせて読んでいる」サイトを知ることができるのと同時に、他のサイトでもあなたのブログが「あわせて読まれる」ようになります。

だそうです。
とりあえずこの日記も参加してみることに。
サイドバーの一番下にぺたりと。
どうなることやら。

フィボナッチ数を返す関数

フィボナッチ数 - Wikipedia
引数で与えた数のフィボナッチ数を求める。
デフォルトは10。
あんまり大きい数を与えると時間がかかるみたい。
50で試してみたらずっと止まってた( ´・ω・`)

def fibonacci(n)
  return 1 if n == 1 or n == 2
  fibonacci(n-2) + fibonacci(n-1)
end

n = ARGV[0] || 10
n = n.to_i
if n < 1
  puts "1以上の整数を入力して下さい。"
  exit
end
puts "Fibonacci(#{n}) = #{fibonacci(n.to_i)}"

フィボナッチ数列を返すクラス

フィボナッチ数を返す関数 - gan2 の Ruby 勉強日記の続き。
引数で与えられた数までのフィボナッチ数列を返すクラス。

class Fibonacci
  def initialize(n)
    @n = n.to_i
    @ary = Array.new

    if n < 1
      puts "1以上の整数を入力して下さい。"
      return
    end

    f(n)
  end

  def f(n)
    if n == 1 or n == 2
      @ary[n] = 1
      return 1
    end

    temp =  f(n-2) + f(n-1)
    @ary[n] = temp
    temp 
  end

  def disp_seq
    @ary.shift # 0番目(先頭)はいらないので削除
    puts @ary.join(", ")
  end
end

n = ARGV[0] || 10
n = n.to_i
if n < 1
  puts "1以上の整数を入力して下さい。"
  exit
end
fib = Fibonacci.new(n)
fib.disp_seq