2013年12月19日木曜日

初めて買ったRubyの書籍がパーフェクトRubyな話。

パーフェクトRubyアドベントカレンダーの19日目です。

正直にお話しします。まだ、あまり読んでいません。


すいません、すいません。
パラパラめくったりはしていますが、他の本を読んでいる微妙なタイミングで買ってしまったのと、今の所Rubyのリファレンスマニュアルを見たりとか、rubyで書かれたコードとかを読みながら、小さなプログラムを組んでいる程度なのでちゃんと読めていないです。手元にあるのにもかかわらず、どこから読んでいいのかわからないという、頓珍漢な答えをしてしまうくらいです。
どこから読もうと思っているのかは、ちゃんとあるので最後の方に書くつもりです。

今、普段書いているのはActionScript3.0 ですが、作業用の補助ツールとかに好んで書いているのはRubyだったりします。

他にもいろいろな書籍があるのに、

「正直にお話しして、まだあまり読んでいないのに何故パーフェクトRubyを最初に選んだか」


という話をします。理由は3つあります。3っつ合わさってこその決め手です。


1. Rubyだから


 もともとフロントエンドで仕事をしていて、ActionScript3.0やJavaScriptを書いていたのですが、どちらもツールとして使うのには扱いづらく、いろいろと他の言語を試してみたりしてました。最初はPHP、次に触ったのはPythonでした。そして、その次に触ってみたのがRubyでした。(※1)
 なんとなく今はRubyがしっくりきている気がしているので、Rubyを使っています。

2. パーフェクトシリーズだから


 PHPを勉強していた時にパーフェクトPHPを買いました。Androidの仕事をした時にパーフェクトJavaを買いました。PHPはあまり使う機会はなかったですが、パーフェクトPHPはフレームワークを作る所の章が今でも参考になっていて、パーフェクトJavaは実際に書く機会があったこともあってとても参考になりました。( ※2 )

3. 読んでみたいと思ったから


 実はプログラマとして最初に触れた自分以外の書いたコードが著者の一人の@sugamasaoさんの書いたコードでした。また最初に一緒にコードを書いたのも@sugamasaoさんでした。学生時代に少しコードを書いていたとはいえ、一人でずっと書いていたこともあって、もう4年前ですが、今でもどういった処理で、どういう目的で書かれていたということをなんとなく思い出せるくらい、とても学んだことがたくさんありました。(自分の書いたコードはすぐ忘れるのに! )

 そういったこともあって、仕事とはあまり関係ないコードで最初にレビューを個人的にお願いしてみたのも@sugamasaoさんだったりします。

 そんな方が共著で一部を書いているRubyの本である。。。。。。あとはわかりますね?


まとめ


 そんなこんなで、買わないわけにはいかない!とおもって、勢いで買ったパーフェクトRubyですが、実はまだちゃんと読めていません。買った理由が完全に個人の経験に依存した理由で、他の方の参考になる気がしません。他の方が参考になる所を書いてくださっているので、自分もそれを参考にしつつ読んでいくつもりです。

 とここまで書きましたが、自分が読もうとしている所は決まっていて、今ちょっとずつサーバーサイドのことを学びつつ、ブラウザで使えるツールなんかをWebrickをつかって書いていたりしていて、ちょっといろいろと学びたいことができてきたので、とりあえず週末あたりにTODOツールを作る所からでも手をつけてみようかなと思っています。

Rubyちゃんと使えるようになりたいぞ!

※1 他の言語をdisれるほどつかってないので、ちゃんとした理由はありません。
※2 よく言えば信頼。わるく言えば妄信。

2013年12月13日金曜日

【CoffeeScript】for文の戻り値メモ

CoffeeScriptの関数は明示的にreturnするべき」って言う記事が流れてきて、CoffeeScriptは触った事なかったけどちょっと気になった事があったのでメモ。

「returnを明示的にしないと元の記事だと無駄なコードが出力される」

 って、さっきの記事にはあったんだけど、Rubyとかもreturnを明示しなくても戻り値のある言語だし、わざわざreturnを明示しなくても戻り値がちゃんとあるというのにはちゃんと意味があると思ってて、できればreturnを明示しなくてもちゃんと期待通りの処理が行われる実装や設計にしていくのが好ましいようなきがした。それを意識して書いてあれば、きっと無駄なコードが出力される事もなさそうな気がする。

そこでRubyのコードとちょっと比較してみた。

 まずはCoffeeScriptのコード
(console.logの戻り値がundefinedみたいなようなのでRubyと同じような結果になるようにputsを定義しています)
01puts = (v)->
02     console.log(v)
03     return v
04  
05sample = ->
06  for i in [0,3,5]
07    puts(i + 1)
08                                                                                                                                                       
09result = sample()
10console.log(result)
結果はこうなる。
11
24
36
4[ 1, 4, 6 ]
次はRubyのコード
1def test
2    for num in [0,3,5] do
3       puts num + 1
4    end
5end
6 
7result = test
8print result
結果はこうなる。
11
24
36
4[0, 3, 5]
この二つを比べてみると、CoffeeScriptとRubyの戻り値の評価の方法が違う事がわかった。

Rubyのリファレンスを見てみると、「 for文はローカル変数のスコープに影響を及ぼさない点が 異なるからです。」ってことなので配列の定義をしている所が最後の評価として返ってきているんだと思う。

CoffeeScriptの方は、for文の中で処理された値を配列にいれて返している。何でそうなっているのかはわからないけれど、そういう評価の方法だとわかっていれば、for文でに保存してそれを配列として返すというjsの出力は無駄というわけではない。

さて、元記事にあるように return文を仕込んだ処理が以下のように書いてあったとする。
01puts = (v)->
02     console.log(v)
03     return v
04 
05sample = ->
06  for i in [0,3,5]
07    puts(i + 1)
08  return
09 
10result = sample()
11console.log(result)
そうすると以下のように処理が行われる。
11
24
36
4undefined
何かが必ず「返り値」になるっていうのは、何がどのような順番で評価されるかって言う事を意識して実装しないとってことで、それは結構プログラムを書く時に意識していた方がいい事だと思うし、戻り値が違うのはテストを書いていたりするとおかしくないのでむやみやたらにreturnで返すよりも、できるだけreturnを返さないように常に戻り値をいしきしてじっそうするほうがいいきがした。

同じような出力を期待するには下のような感じでもできるけど、結局returnは使ってない。return使わなくてもよけいなものを出力しないってことは多分できて、結局作業をする人の慣れとか、その時どんなプロジェクト上の最適化をしなくちゃいけないかって所で、バランスをとっていく所なんだと思う。なので元記事の「必ずreturn」を書くって言うのも一つの方法なんだろうと思う。

ただ、元々のJavaScriptがイケてないからこそ、「JavaScriptに変換する言語を作ろう」みたいになったはずで、そのために使っているはずなのに、出力されるJavaScriptをみてCoffeeScriptの処理の最適化の方法を考えていくのも何となく悔しい気がするのでした。
01puts = (v)->
02  console.log(v)
03  return v
04 
05sample = (list,x=0)->
06      puts(list[x])
07      sample(list,x+1) if list.length > x + 1
08 
09result = sample([0,3,5])
10puts result
書き出されたコード
01// Generated by CoffeeScript 1.6.3                                                                                                                   
02(function() {
03  var puts, result, sample;
04 
05  puts = function(v) {
06    console.log(v);
07    return v;
08  };
09 
10  sample = function(x) {
11    var list;
12    if (x == null) {
13      x = 0;
14    }
15    list = [0, 3, 5];
16    puts(list[x] + 1);
17    if (list.length > x + 1) {
18      return sample(x + 1);
19    }
20  };
21                                                                                                                                                       
22  result = sample();
23                                                                                                                                                       
24  puts(res);
25                                                                                                                                                       
26}).call(this);

2013年12月4日水曜日

Androidの勉強をしよう。

Androidに興味があると言っておきながら、全然目に見える形でアウトプットが出せていないので、Androidの勉強をしたいと思います。というわけで現状を整理。

今、ActionScript3.0を書いていて、それだけだとこの先どうにもならないとおもっているので、ちゃんとアウトプットもしてきたいですね、という所でAndroid勉強しようとか思ってる。あ、でも一応JavaScriptとかを仕事で書いていたときもありました。

Androidに関して言えば、触るのが初めてという訳ではなくてちょっとだけ仕事で実装した程度、Androidの実装されたコードはたまに読んでいるという程度。ただ、細かいデバイス依存の実装や、バージョン互換性の問題等はわかっていないでよくしらないよ、といったところです。

最初にAndroidを触ったときは、助っ人みたいな形だったので(Java書いた事ないのに!)、早急にコードを扱わなくてはいけなくて、

http://dsas.blog.klab.org/archives/52003951.html
http://blog.kmckk.com/archives/3551546.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20091126/341182/

ここら辺とActivityThread.javaとかActivityManager.javaとかのソースを読みつつ、ActivityやIntentのライフサイクルとかを把握してプロダクトコードと格闘してた。
 まぁ、そんなこんなで興味をもつにはもったのだけど、たまにSDKのコードをあさって読んだりしている程度。

さて、いろいろ見てきた所Binderの仕組みを理解するといろいろと理解が深まりそうなのでそこを勉強してきたいです。とりあえずこの辺から見ていきたいと思います。

http://togetter.com/li/110186
https://www.nds.rub.de/media/attachments/files/2011/10/main.pdf


2013年8月28日水曜日

Markdownでドキュメントを書きたい。


Markdownでドキュメントを書きたい。

自分用のメモとかドキュメントとかつくるのにSphinxを使っていたんだけど、どうもなかなかreStructuredTextにこなれないし、自分用にガッツリ勉強する気にもなれない。そのうちGithubのGistを使うようになってきて、Markdown使いたいなって思うようになった。というかGistに張ったものをそのまま使ったり、書いたものをそのままGistに張ったりしたい。

というわけで、Markdownをhtmlに変換できるようなのを探して"markdown html 変換"で検索した所、pandocというのが出てきた。このpandoc、MarkdownをreStructuredTextに変換できるとも書いてあって、じゃあこれを使おうって思った。

とりあえずインストール。Haskellでつくられたツールだそうで、Haskellのパッケージマネージャで入れられるそうだ。
参考 http://qiita.com/sky_y/items/80bcd0f353ef5b8980ee
(※pandoc単体のインストーラもあるっぽい)

といってもHaskellの環境がないので、まずはHaskellの環境をインストールした。

1$brew install haskell-platform
続いてpandocをインストール。たしかこれで動いたはず。
1$ cabal update
2$ cabal install pandoc

インストールできたので、適当に書いて出力してみた。
sample.mdというファイルで作成してsample.htmlというファイルに出力。
01# Sample
02 
03## Gohan
041. Onigiri
052. Katsudon
063. Karaage
07 
08```
09$echo "Onigiri Mogu Mogu"
10```
11---
12 
13```
14$echo "Mecha Mecha Oishi!"
15```

ついで出力。
1$ pandoc sample.md -s -o sample.html


おおっ、ちゃんと出力されてるすげー!。すげーけど味気ない。
味気ないのでCSS当てる事にした。面倒くさいのでGist風のCSSを探してきて拝借。 https://gist.github.com/andyferra/2554919

自分でタグ書くの面倒だからRubyで挿入できるようにした。書いてて、なんだかすごい回りくどい事しているような気がしたけど気にしない。Rubyの勉強したと思う事にした。

01#!/usr/bin/env/ruby
03if __FILE__ == $0
04  usage=  """
05usage
06-------------------
07giss [filename]"""
08  
09  css = """ \"stylesheet\"" href="\"gist.css\"" type="\"text/css\"">"""
10  curdir = Dir::pwd
11  appdir = File.dirname($0)
12  if ARGV.length == 0
13    print usage
14    exit
15  end
16  
17  filename = ARGV[0]
18  file = File.open(filename) do |f|
19    f.read
20  end
21  if file.index("gist.css").nil?
22    n_head = file.index("")
23    file.insert((n_head + 6),("\n" + css))
24    open(filename, "w") do
25      |f| f.write file
26    end
27  end
28  unless File.exist?("gist.css")
29    puts `cp #{appdir}/gist.css #{curdir}/gist.css`
30  end
31end

そうして出てきたのがこちら。


満足。pandocとても良いですね。もっと他の方法もありそうな気がするけどとりあえずこれで。

2013年6月21日金曜日

【JavaScript】Canvasを使ってとりあえず3Dの球を書いてみようと思ったんだけど、いまいちなんだかよくわからない。


ガッと書きたくなって、ざっと書いたので雑だ。
001var Tk = Tk || {};
002 
003Tk.gui = {};
004Tk.canvas = {};
005Tk.t3d = {};
006 
007//テキトーなのでなんとかしたい
008Tk.t3d.objct= null;
009 
010 
011Tk.gui.getElem = function(id){
012    return document.getElementById(id)
013}
014 
015 
016 
017Tk.canvas.getCanvasContext = function(id){
018    var canvas = Tk.gui.getElem(id);
019    if (canvas.getContext) {
020 var context = canvas.getContext('2d');
021    }
022    return context
023}
024 
025 
026Tk.canvas.animate = function(ctx,time){
027    setInterval(
028 function(){
029     Tk.canvas.update(ctx)
030 }
031 ,time)
032}
033 
034Tk.canvas.clear = function(ctx){
035    ctx.fillStyle = "#FFFFFF"
036    ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
037}
038 
039Tk.canvas.setup = function(ctx){
040    var sp= new Tk.t3d.Sphere(200,10,10);
041     
042    Tk.t3d.drawMesh(ctx,sp.points,sp.indices);
043    Tk.t3d.object = sp;
044}
045 
046//更新しているけど、別に動いていない。
047Tk.canvas.update = function(ctx){
048    Tk.canvas.clear(ctx);
049    var sp = Tk.t3d.object;
050    Tk.t3d.drawMesh(ctx,sp.points,sp.indices);
051}
052 
053Tk.t3d.Point3d = function(x,y,z){
054    this.x = x;
055    this.y = y;
056    this.z = z;
057}
058 
059Tk.t3d.Point = function(x, y){
060    this.x = x;
061    this.y = y;
062}
063 
064Tk.t3d.Sphere = function(r,rows,cols){
065    this.r = r;
066    this.rows = rows;
067    this.cols = cols;
068    this.points = setPoints(r,rows,cols);
069    this.indices = setIndices(r,rows,cols);
070     
071    function setPoints(r,rows,cols){
072 var pList = [];
073 for(var i = 0;i < rows; i++){
074     for(var j = 0;j < cols; j++){
075  var angle1 = Math.PI * 2 / ( cols -1 ) * j
076  var angle2 = Math.PI * i / ( rows -1 ) -Math.PI/ 2;
077  var point = new Tk.t3d.Point3d(
078      r * Math.cos(angle1) * Math.cos(angle2),
079      r * Math.sin(angle1) * Math.cos(angle2),
080      r * Math.sin(angle2)
081  );
082  pList.push(point)
083     }
084 }
085 return pList;
086    }
087 
088 
089    function setIndices(r,rows,cols){
090 var indices = [];
091 for(var i = 0;i < rows;i++){
092     for(var j = 0;j <cols; j++){
093  if( i < rows - 1 && j < cols -1){
094  indices.push([
095      i * cols + j,
096      i * cols + j + 1,
097      (i + 1) * cols + j])
098  indices.push([i * cols + j + 1,
099        (i + 1) * cols + j + 1,
100        (i + 1 ) * cols +j]);
101  }
102     }
103 }
104 return indices;
105    }
106}
107 
108Tk.t3d.toPersePectionPoints = function(points){
109    var parsePection = 200;
110    var forcalLength = 250;
111    var pList = [];
112    for(var i = 0; i < points.length;i++){
113 var scale = forcalLength / ( forcalLength + points[i].z + parsePection)
114 pList.push(new Tk.t3d.Point(points[i].x * scale, points[i].y * scale));
115    }
116    return pList;
117}
118 
119Tk.t3d.draw3d = function(ctx,points){
120    var drawPoints =Tk.t3d.toPersePectionPoints(points)
121    for(var i = 0; i < drawPoints.length;i++){
122 ctx.beginPath();
123 ctx.arc(drawPoints[i].x + 100, drawPoints[i].y + 100, 1, 0, Math.PI*2, false)
124 ctx.fill();
125    }
126     
127}
128 
129Tk.t3d.drawMesh = function(ctx,points,indices){
130    var drawPoints =Tk.t3d.toPersePectionPoints(points)
131    var offsetX = ctx.canvas.width / 2;
132    var offsetY= ctx.canvas.height / 2;
133    for(var i = 0; i < indices.length;i++){
134 var index = indices[i]
135 ctx.beginPath();
136 ctx.moveTo(points[index[0]].x + offsetX  ,points[index[0]].y + offsetY );
137 ctx.lineTo(points[index[1]].x + offsetX  ,points[index[1]].y + offsetY);
138 ctx.lineTo(points[index[2]].x + offsetX  ,points[index[2]].y + offsetY );
139 ctx.lineTo(points[index[0]].x + offsetX  ,points[index[0]].y + offsetY);
140 ctx.stroke();
141    }
142     
143}
144 
145Tk.t3d.main = function(){
146    var ctx = Tk.canvas.getCanvasContext("canvas_20130621");
147    Tk.canvas.setup(ctx);
148    Tk.canvas.animate(ctx,200);
149}
150 
151Tk.t3d.main();

2013年3月12日火曜日

【Ruby】WebrickのProxyContentHandlerとProcクラス



前々回の記事webrickでプロキシサーバをつくろうとしてデータを書き換えたりするために使っていた際、ハンドラのProxyContentHandlerにProcクラスを使っていたけれど これをどうにかして、別のクラスにして置き換えたいと思った。
1handler = Proc.new(){|req,res|
2 
3  if "#{req.host}#{req.path}" == REPALCE_TARGET
4    res.body = REPLACE_CONTENT
5  end
6}
Procについて調べてみて出てきた説明がこちら
ブロックをコンテキスト(ローカル変数のスコープやスタックフ レーム)とともにオブジェクト化した手続きオブジェクトです。
うむ、いまいちどうしたらいいのかわからなかったのでいろいろと試行錯誤しようとしたけれど、なかなかうまくいかなかった。そこで、とりあえず適当にクラスをつくって突っ込んでみる事にした。
1class Handler 
2  def initialize()
3  end
4end
これを
1handler= Handler.new
として、プロキシを設定し、適当なページにアクセスすると以下の表示が帰ってきた。
1Internal Server Error
2 
3undefined method `call' for #
4WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) at doc.ruby-lang.org:80
5
methodのcallが無いという事なので、Procの時に実装していた引数をもたせたcallというメソッドを実装
1class Handler
2   
3  def initialize()
4  end
5   
6  def call(req,res)
7  end
8   
9end
すると、ページがきちんと表示された。よし、これにて一件落着。 といいたい所だけれども、とりあえずwebrickのhttpproxy.rbとproc.cを見てみた所、何となく、これでも問題なさそうだ。

https://github.com/ruby/ruby/blob/trunk/proc.c https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpproxy.rb

 動くっちゃ動くけど、この実装はruby的にいいのかどうか。

2013年2月25日月曜日

【Ruby】yamlをrubyで書き出そうとしたときのメモ


設定ファイルの書き出し、書き込みみたいな事がしたかったので調べてて
使った事無かったyamlを使ってみようと思った。なんか見やすいですしおすし。
1Animal:
2 gorira: Goritaro
3 cat  : Nyanko
4 horse : Umazo
こんな風にかける。 ファイルに書き出したかったので、調べてみると、
1open("./test.yml","w") do |f|
2 YAML.dump(hoge,f)
3end
でファイルに書き出せるっぽい。しかもrubyで書いたオブジェクトをそのままの形で書き出す事ができると、どこかで見た気がしたので、下みたいに書いて出力してみた。
01#!/usr/bin/ruby
02require "yaml"
03 
04hoge = "test1"
05fuga = "test2"
06 
07class Hoge
08  attr_accessor :hoge,:fuga
09   
10  def initialize(hoge,fuga)
11    @hoge = hoge
12    @fuga = fuga
13  end
14end
15 
16class Piyo
17  attr_accessor :piyo
18 
19  def initialize(piyo)
20    @piyo = piyo
21  end
22end
23 
24piyo = Piyo.new(fuga)
25hoge = Hoge.new(hoge,piyog)
26sample = hoge.to_yaml
27 
28open("./test.yml","w") do |f|
29  YAML.dump(hoge,f)
30end
すると、こんな風に書き出された。
1--- !ruby/object:Hoge
2hoge: test1
3fuga: !ruby/object:Piyo
4  piyo: test2

違う!わたしが欲しいのはこんなYAMLちゃんじゃないわ!!!1
なんか’!ruby’とか入ってるのは、rubyのオブジェクトだからっぽい。
1hoge = {'Hoge' =>{'hoge'=>'test1','Piyo'=>{'piyo'=>'fuga'}}}
これだと普通に出力されました。
1---
2Hoge:
3  hoge: test1
4  fuga:
5    piyo: test2
これだよ!ほしかったのは

そこで、調べてみるとオブジェクトの’taguri’と'to_yaml_style'というのを書き換えてあげるといいといいらしい。いいらしいがうまくいかず(前確かめたときはちゃんとできたのに)。
(gihyo 言語別 YAML用ライブラリ徹底解説)

いろいろと検索結果をぶらぶらとしていて、たどりついたココ(YAML/オブジェクトシリアライズ処理を読む)に習って、rubyのソースを'to_yaml'で検索してみるとそれっぽいのが出てきました。
ちなみに確認したバージョンはruby-1.9.3-p392
01#ext/syck/lib/syck/rubytype.rb
02class Object
03    yaml_as "tag:ruby.yaml.org,2002:object"
04    def to_yaml_style; end
05    undef to_yaml_properties rescue nil
06    def to_yaml_properties; instance_variables.sort; end
07 def to_yaml( opts = {} )
08  YAML::quick_emit( self, opts ) do |out|
09            out.map( taguri, to_yaml_style ) do |map|
10    to_yaml_properties.each do |m|
11                    map.add( m[1..-1], instance_variable_get( m ) )
12                end
13            end
14        end
15 end
16    alias :syck_to_yaml :to_yaml
17end

これだけ見てもさっぱりわからないですね。と、ここまでやって思ったんだけど、よくよく考えると今やりたいことはyamlでやる必要ないかなぁと。(←今ココ

rubyでyamlを書き出そうとして、なんとなしにrubyのライブラリのソースにたどり着いたので、いろいろと中身も見ていければなぁと思ったりしましたメモでした。(まわりくどい)

 ※文体変えた

2013年2月22日金曜日

【Ruby】WEBrick でプロキシサーバをつくってみる


Macのブラウザでネットワーク関連の処理をあれこれしたいと思った時に、Windowsを利用していた時に使っていたFiddler的なものが欲しくなりました。WEBrickを使ってプロキシサーバをつくれば、似たような事ができる(?)と教えていただいたので、早速試してみる事にしました。 

サーバサイドのスクリプトも、Ruby自体もあまり触った事がなかったので、ついでにどんな風にかけるのかあれこれいじりながらやってみる事にしています。いろいろとやってみたい事があるのですが、とりあえず置き換えの方法だけでもメモしておきます。

 Webrickを利用している部分は抜き出してクラスに。まだまだいろいろと機能があるようなのでいじりながら何ができるかを検討中。
01##./lib/proxy.rb
02#!usr/bin/ruby
03require 'webrick'
04require 'webrick/httpproxy'
05include WEBrick
06 
07class Proxy
08   attr_accessor :config
09 
10  def start
11    print @config
12    @server = WEBrick::HTTPProxyServer.new( @config )
13    Signal.trap('INT') do
14     @server.shutdown
15    end
16    @server.start
17  end
18 
19  def shutdown
20    @server.shutdown
21  end
22    
23end
設定ファイル(yml)
1server:
2 :BindAddress    : '127.0.0.1'
3 :Port           : 10080
4 :DocumentRoot   : ''
5 :CGIInterpreter : '/usr/bin/ruby'

handlerの中身の部分は、あまりいろいろ試してみていないのでこれからいろいろと試しつつ、できそうな事があれば実装していこうと思います。URLを比較する部分とかはまだ適当です。
01##./main.rb
02#!usr/bin/ruby
03require './lib/proxy.rb'
04require 'yaml'
05 
06@server = Proxy.new
07 
08REPLACE_CONTENT =<<EOF
09<body>
10<h1>Oh!</h1>
11<body>
12EOF
13 
14 
15REPALCE_TARGET = "tsukajizo.com/"
16 
17def start_proxy
18  #Handler
19  handler = Proc.new(){|req,res|
20 
21    if "#{req.host}#{req.path}" == REPALCE_TARGET
22      res.body = REPLACE_CONTENT
23    end
24  }
25   
26  #プロキシサーバの設定
27  config = YAML.load_file('./config.yml')
28  server_config = config['server']
29  server_config[:ProxyContentHandler] = handler
30   
31  #プロキシサーバの起動
32  @server.config = server_config
33  @server.start
34end
35 
36start_proxy
なんか、こうもうちょっと使いやすい感じにしていきたいですね。

とりあえず。
 →

こんな感じです。