Ruby / Ruby on Railsを中心にした、プログラミング技術に関しての話題

タグ:  

[スポンサー広告]スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書く事で広告が消せます。

タグ:   linux *   git *  

[GNU / Linux]グレードアップに伴うgitのエラー

先日、自宅のDebianサーバをlennyからsqueezeにアップグレードをおこなったのですが、それいこうgit-daemonの調子がおかしいです。

Gitでpushしようとすると、以下のようなエラーメッセージが表示されてpushが失敗します。

$ git push origin master
fatal: The remote end hung up unexpectedly

原因は、いつかあるようです。

そのうちの一つが起動オプション。
こちらのブログエントリ「[git-daemon]git-pushすると「fatal: The remote end hung up unexpectedly」というエラーが発生する - func09」を参考にしました。

もう一つは、リポジトリのobjectsとrefsのパーミッション。
パーミッションを変更すると、エラーはすべて消えました。
なお面倒なので、リポジトリフォルダ全部パーミッションの変更をおこなっています(git-daemonのbase-pathが/var/git-ripos、プロジェクトがfirst_appの場合)。

$ sudo chown -R gitdaemon /var/git-ripos/first_app

以前のバージョンでは普通に使えていたので、squeezeにしたことによるgit-daemonのバージョンアップでの変更によるものと考えられます。
gitdaemonという管理用ユーザが自動的に作られ、git-daemonはそのユーザ経由で処理をおこなうようになったようですね。

タグ:   ruby *   プログラミング *   programming *   scheme *  

[Ruby]リストをつくる

新しいブログサイト「アルミナ解析研究所」のほうには人が来てくれない・・・。

まあいいか。それにしてもサイト名が似ているので、こっちは改名したほうがいいかも。

さて今回は、Schemeについて。
Lisp系の言語の基本的なデータ構造は、carとcdrという部分からなるコンスセルと呼ばれるものです。
リストは自前Schemeインタプリタ「Lisrb」ではArrayクラスをそのまま転用していました。
RubyのArrayをリストとしてもちいることは可能でしたが、きちんとしたListクラスを作成することにします。
それによって、ペアの表現もすんなりおこなえるようになりました。

こちらのブログを参考にしています。
リスト構造の要素から、条件を満たす要素を取り出す - バリケンのRuby日記 - Rubyist
Rubyでリスト構造 - 趣味的にっき

class List < Struct.new(:car, :cdr)
  include Enumerable
  alias :a :car
  alias :d :cdr
  private :a, :d
  
  def initialize(car = nil, cdr = nil)
    super
    a = self
    a = a.cdr until a.cdr.nil?
  end
  
  def last_cdr
    a = self
    a = a.cdr until a.cdr.nil?
    return a
  end

  def last_cdr=(x)
    last_cdr.cdr = x
  end

  def add_last(x)
    @llast_cdr = last_cdr.cdr = List.new(x) 
  end

  def push(x)
    if self.car
      add_last(x)
    else
      self.car = x
    end
    self
  end
  alias :"<<" :push

  def size
    inject(0) {|n, a| n += 1 }
  end

  def each
    a = self
    begin
      yield(a.car)
    end while a = a.cdr
  end

  def to_s(nest_level = 0)
    result = if self.cdr
               if self.cdr.is_a? List
                 self.car.to_s + ' ' + self.cdr.to_s(nest_level + 1)
               else
                 self.car.to_s + ' . ' + self.cdr.to_s
               end
             else 
               self.car.to_s
             end

    return nest_level > 0 ?  result : '('+ result + ')'
  end

  def method_missing(m, *args)
    if m[0] == "c" and m[-1] == "r" and m.to_s.size > 2
      return m[1..-2].each_char.inject(self) {|l, c| l.send(c) }
    else
      super
    end
  end

  def respond_to?(m, include_private = false)
    if m.to_s =~ /^c[a|d]+r$/
      true
    else
      super
    end
  end
end

基本的には参考サイトと同じで、以前作成した自前のパーサに組み合わせるために、いくつかのメソッドを追加しています。

なお、パーサの導入は簡単でしたが、自前のSchemeインタプリタに正式に導入するとなると、Arrayから新しいListに切り替えることとなり、影響範囲が大きくなりすぎに考えられるので、手をつけていません。

method_missingを使って、carとcdrの組み合わせでデータを取得する操作(caarだとcarのcar、cdarだとcdrのcarのような)を可能にしています。
以前のAliasと可視性についてのブログエントリは、このプログラムがもとでした(このプログラムを作成したのは結構前のこと)。

SchemeではBiwaSchemeっていう実装があるみたいで、実はそれに注目しています。
VMをつかったインタプリタで、ちょっとみたかんじなんだか難しそうでした。
Lisrbとはかなり違っているみたいだったので、Lisrbのほうはそっとしておくことにして、そちらのほうをかんがえてみようかな。。。
そういえばGaucheもVMタイプだとどこかできいたような。

タグ:  

[Ruby]ブログ刷新計画

しばらくブログ投稿が滞ってしまいましたが、その間、ブログアプリをつくっていました。

こちら「アルミナ解析研究所」です。

オープンソースのブログアプリ(主にLokkaなど)を参考にSinatra+ActiveRecordで構成されています。
運用にはHerokuを利用しています。

Herokuについては雑誌によい記事が載っていて、それを見ながら設定等おこないました。



自前ブログは、実は計画はかなり前からやりたいなと思っていて、オープンソースのものを導入して勉強しつつ使おうかとも考えたのですが、結局自分で完全にコントロールできるWebアプリのプロジェクトがあったほうがよいという考えから、一からつくりました。

機能は個人使用ということでかなりシンプルなものなのですが、思ったより時間もかかり、かなり大変でした。
1月いっぱいにはできる、バレンタインデーにはできる、と予想していたのですが、実際バレンタインデーくらいにはもうたいがい完成したのですが、なんだかんだとオープンが先延ばしになってしまいました。
このツメの甘さというか、どたんばの足腰の弱さは、性格的なものなのかもしれないです。なんとかしないと。
その他、作成にかかりきりになると、ブログ投稿を放置するなど、余裕がなくなってまわりが見えなくなる、オーバーペースになる。そして、だいたい完成がみえてくると安心して気が抜ける、っていうのもよくなかったですね。
こういう感じで反省点がかなりあります。技術的なものに関してはなおあります。

それはともかくとして。
新しいほうに移行しないといけないですね。
こちらのブログをほったらかしにするわけにもいかないし、新ブログの案内を出しつつ徐々に向こうをメインにしていけたらなとおもっています。

タグ:   ruby *   プログラミング *   programming *  

[Ruby]aliasの可視性

aliasの可視性について調べました。
メソッドに別名をつけるときに使うaliasですが、aliasで追加したメソッドの可視性のあつかいはどのようになるのか。
もともとのメソッドと、別名メソッドの可視性を変えたいようなケースなど、ちょっと気になったので、実験してみました。

class A
  def foo
    puts "foo"
  end

  def bar
    f
  end

  private
  alias :f :foo
end

a = A.new
a.foo
a.f

まず上記のようなプログラムを用意しました。
メソッドfooを定義し、aliasによってfooにfという別名つけています。
aliasをprivate指定ののちにおこない、可視性はどうなるかを調べてみます。

実行結果をみてみると。

$ ruby alias_test.rb
foo
foo

fもpublicとして定義されています。

では、fooをprivateメソッドとして定義すると。

class A
  private
  def foo
    puts "foo"
  end

  def bar
    f
  end
  
  alias :f :foo
end

a = A.new
begin
  a.foo
rescue => e
  p e
end
begin
  a.f
rescue => e
  p e
end

実行結果はつぎのようになります。

$ ruby alias_test.rb
#<NoMethodError: private method `foo' called for #<A:0x975d024>>
#<NoMethodError: private method `f' called for #<A:0x975d024>>

両方共、privateメソッドになっています。
aliasは可視性ももとのメソッドのものを引き継いでいるようです。

これはつぎのように、privateに引数でメソッドを指定することで、かえることができます。

class A
  def foo
    puts "foo"
  end

  def bar
    f
  end
  
  alias :f :foo
  private :f
end

a = A.new
a.foo
a.bar
a.f


$ ruby alias_test.rb
foo
foo
alias_test.rb:30:in `<main>': private method `f' called for #<A:0x9c9e678> (NoMethodError)

タグ:   ruby *   プログラミング *   programming *  

[Ruby]insectとto_s

inspectとto_sのちがいについて調べてみました。

参考にしたのは、こちら。
Why do this Ruby object have two to_s and inspect methods that do the same thing? Or, so it seems. - Stack Overflow

この両者はともに、表示メソッドを呼び出したときにフックされるメソッドのようです。
なにがちがうのかというと、inspectはpメソッドを、to_sメソッドはputsやprintメソッドを使ったときに、それぞれ呼び出されるということです。

役割のちがいとしては、inspectは主に開発者のデバッグの用途に、to_sはエンドユーザへの表示に使うというように上記サイトでは提案されています。

ともにObjectクラスのインスタンスメソッドですが、それぞれのクラスで適宜オーバーライドして使うとよさそうですね。

では実際に動かして試してみます。(サンプルプログラムは参考元のものを簡略化してみました)

class Test
  def initialize
    @a = Array.new
    @b = Array.new
  end
  
  def to_s
     "call to_s"
  end 

  def inspect
     "call inspect"
  end
end

if __FILE__ == $0
  test = Test.new
  p test
  print test
  puts test
end

「__FILE__ == $0」はテストコードをくっつけているコードとかで見かけることがありますね。
現在実行中のスクリプトが、ファイル名と同じものの場合、この条件は真になります。
なので、requireなどで使う場合には条件が偽となり表示処理はおこなわれず、このスクリプト単体で実行する場合にだけ、表示処理を実行させることができるようになります。

実行結果は次のようになりました。

call inspect
call to_scall to_s

pではinspectが、printとputsではto_sが呼ばれています。
printは改行をおこなわないので、putsの結果とくっついています。

なお、サンプルのクラスのinspect、to_sを消して実行してみると結果は次のようになりました。

#<Test:0x9728964 @a=[], @b=[]>
#<Test:0x9728964>#<Test:0x9728964>

いずれもオブジェクトの情報が表示されますが、inspectのほうがよりくわしくインスタンス変数の情報まで表示させています。

カレンダー
04 | 2012/05 | 06
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
検索フォーム
ブックマーク登録
FC2ブログランキング
バナー
タカミコーポレーションフリーイラスト集
ブロとも申請フォーム
スポンサードリンク
QRコード
QR

Page Top

Powered by FC2 Blog |

FC2Ad

FC2ブログ | Template Design by スタンダード・デザインラボ