RubyのStructの簡易版実装してみた
30分くらいでできる簡単な問題探しててmzpさんのやつを見つけてそれを解いてみてる.
これが動けばいい
Dog = MyStruct.new(:name, :age) fred = Dog.new('fred', 5) fred.age = 6 printf "name:%s age:%d\n", fred.name, fred.age
回答
class MyStruct def self.new(*names) Class.new do |_obj| def initialize(*values) @__values = values end names.each_with_index do |method, i| class_eval <<-EOS def #{method} @__values[#{i}] end def #{method}=(value) @__values[#{i}] = value end EOS end end end end
参考
モナディックなパーザーコンビネータ作ってみた
タイトル通りで作ってみたました. もともと研究で違うことやってたはずなのに目的を見失ってなんか面白そうだしこれならゼミで話しても怒られなさそうという考えからこの頃ずっと勉強してた.
OCamlで実装しようかHaskellで実装しようか迷っててどっちでも良かったんだけど最終的にはHaskellで書いた. 最初はOCamlの勉強も少ししてて、とにかく本を買いたくなかったので以下のページを読んでた.
けど素直にHaskellでやったほうが楽そうという気持ちになり途中からHaskellに切り替えた. Haskellの文法は雰囲気がわかる程度だったのでなんとかなるだろうと思い特に何もしなかった. モナドは「モナドは単なる自己関手の圏におけるモノイド対象だよ。何か問題でも?」という感じだったので以下のページを読んでだ.
パーザーコンビネータはググるといろんな人が実装しててるのでそれを参考にするといいかもしれない. こんなふうにParserの型が決まった時点で考えることはあんまりなくて型すごいって思いながら実装しいくとできたし型すごい.
type Result = Either String type Parser v = StateT String Result v
PEGパーザにした気でいるんですがもしかしたらこれではいけないかもしれないので間違っていたらスマンという感じです.
import Control.Monad.State import GHC.Base((<|>)) import Data.Char type Result = Either String type Parser v = StateT String Result v runParser = runStateT look :: Parser Char look = do x:_ <- get return x item :: Parser Char item = do x:xs <- get put xs return x satisfy :: (Char -> Bool) -> Parser Char satisfy f = do a <- item if f a then return a else mzero unsatisfy :: (Char -> Bool) -> Parser Char unsatisfy f = satisfy (not . f) cjoin :: Parser a -> Parser a -> Parser [a] cjoin p1 p2 = do a <- p1 b <- p2 return [a, b] select :: Parser a -> Parser a -> Parser a select = (<|>) many :: Parser a -> Parser [a] many f = many1 f <|> return [] many1 :: Parser a -> Parser [a] many1 f = do a <- f b <- many f return $ a:b
例えばExpr <- Number + Number
を受理するためのは以下のように書くとちゃんと計算結果が返ってくる.
number :: Parser Integer number = do n <- many1 digit return $ read n where digit = satisfy isDigit expr :: Parser Integer expr = do a <- number op <- token (=='+') >> return (+) b <- number return $ op a b main :: IO () main = print $ runStateT expr2 "1+2;" -- => Right (3,";")
4則演算バージョンがあるのでぜひ
参考
- http://d.hatena.ne.jp/kazu-yamamoto/20080920/1221881130
- http://www.geocities.jp/m_hiroi/func/haskell32.html
感想
ruby2.2.2で現在実行中の関数名を取得する
前提
ganmacs@ganmacs~% ruby -v ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
内容
現在実行中の関数名を取得したいとき、ruby 1.8までは以下のようにしてとれた。
しかし1.9からto_s(Array)
の挙動が変わったらしく2.2.2では動かなった。
class Object def current_method caller.first.scan(/`(.*)'/).to_s end end # when ruby version is 1.8 or earlier puts current_method #=> "<main>" # when ruby verison is 1.9 or later puts current_method #=> [["<main>"]]
なので今は以下のように書くと実行中の関数名を取得できる
class Object def current_method_name caller.first.match(/`(?<method_name>.*)'/)[:method_name] end end puts current_method_name #=> "<main>"
参考
Working With TCP Socketsを読んだ
研究してるふりをして全くせずにこれよんだ。
Working With TCP Sockets (English Edition)
- 作者: Jesse Storimer
- 発売日: 2012/10/24
- メディア: Kindle版
- この商品を含むブログを見る
なぜ読んだかというと、少し前にこの記事いいよって教えてもらった記事があって読んでてたまたまそこに書いてあったから yuuki.hatenablog.com
雑にメモとか取りながら読んだのぜひ github.com
感想
webサーバの実装モデルっぽいのもがわかりやすく紹介されていて非常に面白かった。
英語よめるようになったし、これからも研究してるふりして積極的に関係ないことやっていくぞ!!!
while (token = lexer.read) != EOFをEnumeratorをつかってどうにかしたい
あたらしく研究室に入って(2度目)スクリプト言語の作り方って本が課題なのでやっていまして、そのときlexer作るんですが
while (token = lexer.read) != EOF ... end
的な書き方してて嫌な気持ちになったので他にまともな書き方がないか調べました.
どうしたいか
- while とかの中で代入はすきじゃないのでしたくない
- eachみたいにつかえる
- けど,任意の位置でreadできるようにしたい
- しかしメモリ使用量を抑えたいので一気に配列に突っ込むとかはしたくない
つまり下みたいにはしたくない
# ファイルひらいて一気に配列に突っ込む file = open(file_name).map { |f| f.strip } file.each do |f| ... end
どうしたか
Enumerator classを使いました.
例として以下の様なこと Enumerator
を使ってやってみました.
ファイルから1行ずつ読んでくる->読んできた1行になにかする(行番号をつける).
javaのLineNumberReader
みたいなやつ
class LineNumberReader def initialize(filename) @filename = filename end # nextがなかったらStopIterationをraiseする def read_line file.next end def peek_line file.peek end def has_next_line? !!file.peek rescue StopIteration false end # loopはStopIterationをrescueする def each loop { yield(read_line) } end private # each_line, with_indexは enumeratorを返すのでnextとかで逐次に取ってくるはず def file @file ||= open(@filename).each_line.with_index end end
LineNumberReader#file
がEnumerator
を返すようにしているので[メモリ使用量を抑えたいので一気に配列に突っ込むとかはしたくない]は解決出来てるはず
またLineNumberReader#read_line
を外から呼ぶようにすることで[任意の位置でreadできるようにしたい]も解決できる
reader = LineNumberReader.new('file.rb') p reader3.read_line ... p reader3.read_line if reader3.has_next_line?
またLineNumberReader#each
を作ってることで[eachみたいにつかえる]も解決
reader = LineNumberReader.new('file.rb') reader.each |f| ... end
while
使いたいときはloop
を使うと(実際eachで解消されてるけど)[while とかの中で代入はすきじゃないのでしたくない]も解決
reader = LineNumberReader.new('file.rb') loop p reader.read_line end
まとめ
ただのiteratorっぽいなにかだし,こんなことしてないで早く課題終わらせたほうが良さそう もっと賢い方法があればだれか教えてくれ!!
2週間でできる! スクリプト言語の作り方 (Software Design plus)
- 作者: 千葉滋
- 出版社/メーカー: 技術評論社
- 発売日: 2012/02/10
- メディア: 単行本(ソフトカバー)
- 購入: 11人 クリック: 318回
- この商品を含むブログ (18件) を見る
ansibleっぽいitamaeっぽいプロビジョニングツールminarai作った
作りました. ansibleとitamaeの名前を出しましたがお手本にしたのは @r7kamuraさんが作ったr7kamura/serverkit · GitHub というgemです.
動機
これが欲しかったわけではないんですがgem作ったことなかったし作りたいものもなかったのでなんか真似しようとおもって色々探してたらserverkitが出てきてちょうどよかったので自分でも書いてみました.
使い方
一番シンプルな使い方はrecipe.yml
を以下の内容で作って
- name: clone codic-clojure type: git repository: https://github.com/ganmacs/codic-clojure.git destination: codic-clojure - name: clone dot_emacs type: git repository: https://github.com/ganmacs/emacs.d.git destination: .emacs.d
以下のコマンドを実行するだけです.また、既に目的のファイルが存在する場合などはスキップされるようになってます.
$ minarai recipe.yml INFO : Minarai starting... INFO : [SKIP] clone codic-clojure INFO : [DONE] clone dot_emacs INFO : Minarai finish
以上でgit cloneしてきてくれます.
変数を使った場合
recipeに変数を使うこともできます.
まずvars.yml
に以下を記述します.
remote_dotfile_repo: git@github.com:ganmacs/dotfiles.git tmp_dir: /Users/ganmacs/tmp dotfile_path: /Users/ganmacs/tmp/dotfile vim_config_in_dotfile: /Users/ganmacs/tmp/dotfile/vim/vimrc dot_vim_path: /Users/ganmacs/tmp/.vim
そしてrecipe.yml
に以下を記述します
- name: install vim type: homebrew item: vim - name: create tmp directory type: directory destination: <%= tmp_dir %> - name: clone dotfile type: git repository: <%= remote_dotfile_repo %> destination: <%= dotfile_path %> - name: link dotfile to hgoe type: link source: <%= vim_config_in_dotfile %> destination: <%= dot_vim_path %>
そして実行すれば終わりです
$ minarai recipe_erb.yml.erb --variables=vars.yml INFO : Minarai starting... INFO : [SKIP] install vim INFO : [DONE] create tmp directory INFO : [DONE] clone dotfile INFO : [DONE] link dotfile to hgoe INFO : Minarai finish
機能
とにかくシンプルにしたくて他の構成管理ツールみたいに高機能なものを作るのはやめました. 基本的にローカルのMacの構成管理のためにしか使う気はないのでsshもできないです. コマンドも実行するrecipeを渡すだけです.(変数は使えますが)
実行できるタスク(アクション)は以下のとおりです
- git - git cloneしてきます
- file - fileのコピーをします
- link - symlinkをはります
- directory - directoryを作ります
- homebrew - homebrewでパッケージをインストールします
- homebrew_cask - homebrew_caskでappをインストールします
- url_get - 指定したurlからcurlしてきます
感想
ansibleとitamaeはすごいなーって感想とserverkitのコードが読みやすくて最高って感じでした.
今後
rbenvとかdefaultとかcommandのactionも増やして構成管理に使っていきたい
関連
リクルートのインターンで負けてきました
まとめ
型環境、そもそもなんのことだかよくわかってないのにどうしてこうなった!!!!お茶大生!!いい加減にしろ!!!!
— がんま (@ganmacs) 2015年2月18日
— がんま (@ganmacs) 2015年2月23日
概要
http://recruit-jinji.jp/winter-internship2015/
リクルートホールディングスのApplication Engineerコースに行ってきました。 ぼくはApplication Engineerコースの中の「インフラ/DB/バックエンドエンジニア」コースに申し込みました。 日程は2月1日から2月23日までで、コードを書くだけで15万もらえて人のお金で美味しいごはん食べられて交通費、宿泊費まで出る最高な感じでした。 やったこととか選考方法とかは他の人が書いているのでそちらを見てください。
リクルートインターンの良かったところ
僕が思ったインターンの良かったところを書きます
ずっとコード書いていられる
最初の3日間を企画を考える+座学に使います。 あとは、基本的にずっとコード書いていてよかったので開発に集中できてとてもいい環境でした。 聞きたいことがあればメンターがチームに1人ついているので聞くこともできてこれもまたいい環境だなと思いました。 また、週に1回メンターとの時間も設けられていたりもしました。
とにかくうちのチームのメンター氏はいい人で非常に勉強になることが多かったです。
AWS使い放題
AWS上にアプリをおいて開発するのでAWSが使い放題でした。 これが本当によくて自分はAWS使ったことなかったんですが試して壊してを繰り返せたりして勉強になりました。
使い放題だったこともあり、てきとうにインスタンスを立ち上げてitamae走らせてすぐインスタンス壊すみたいな無駄なことができます。最高です。
インターン中に企画がある
インターン中に「天下一自動化大会」っていうの企画が1日あってそれが結構楽しかったです。 この企画は自分の身の回りで自動化できそうなことを自動化して一番良さそうなやつを決めるみたいなあれです。
僕はchef使って環境構築自動化したのとemacsからコマンド一つでgithubのコミットひらけるプラグイン作りました。
美味しいご飯が食べれる
ご飯の参考画像です 天国
ほかにもみんなが書いてくれるはず
実際やったこと
バックエンド1人、フロントエンド2人のチームで「デートコース共有アプリ」をつくりました。 フロントエンドの2人が頑張ってくれて気づいたらミュゼっぽいおしゃれランディングページとか出来てました。(本番だとフォントととかもちゃんとしてる)
僕はすこしRailsかいてあとはインフラやってました。 サーバの構築にitamaeを使ったり、サーバのテストとしてserverspec使ったり、capistranoとcircle ci使ってデプロイ自動化したりして最高に楽しかったです。
その辺で得た知見はまた別エントリで残したいと思います。
来年あるかしらないけど行くと良さそうな人
- あたりまえだけどエンジニアになりたい人
- エンジニアの友達が周りにいない人
- 2月暇で死にそうな人
- 寿司が食べたい人
感想
選考とかあるけど実際ちょろいしみんなインターン行って寿司と15万ゲットした方がいいと思いました!!!
どう考えても完全にうちのチームが一番最高だった!!!!
他のインターン生が書いた参加ブログ
「Recruit Holdings Winter Internship 参加」って書けばいいと思ってる他のインターン生のブログです