Archive for the ‘ruby’ Category

    はてなブックマーク - ファイル・ディレクトリ名コレクション
    このエントリーをはてなブックマークに追加

    Fusic 中野です。
    暑い中昼休みにゲームソフトを買いに行ったら、来週発売でした。

    ちょっとした小ネタ。

    弊社は主にRubyかPHPでプログラムを書くことが多い会社なので、今回はGo言語とHaskellについて
    書いてみようかと思います。

    Haskell製の自作ツールをGo言語で書き直していたのですが、あるディレクトリ配下のファイル一覧を
    取得する処理を簡単に記述できたので、ちょっと比較をしてみようかと思います。

    Go言語(MacOSX go1.3 darwin/amd64)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    package main
    import (
    	"fmt"
    	"os"
    	"path/filepath"
    )
     
    func main() {
    	var result []string = make([]string, 0) // グローバルはいや!
    	walk := func (p string, info os.FileInfo, _ error) error {
    		if info.IsDir() {
    			result = append(result, "Directory: " + p)
    		} else {
    			result = append(result, "File: " + p)
    		}
    		return nil
    	}
    	filepath.Walk(".", walk)
    	fmt.Println(result)
    }

    Haskell(MacOSX ghc version 7.6.3)

    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
    
    module Main where
     
    import Control.Monad.Writer
    import Control.Monad.State
    import System.FilePath
    import System.Directory
     
     
    main :: IO ()
    main = go "." >>= print
        where
            go p = execWriterT $ runStateT walk [p] -- go :: FilePath -> IO [FilePath]
            walk = do -- walk :: StateT [FilePath] (WriterT [FilePath] IO) ()
                p <- get
                case p of
                    (x:xs) -> do
                        d <- lift . lift $ doesDirectoryExist x
                        if d then do
                            files <- lift . lift $ getDirectoryContents x
                            put $ xs ++ [x </> f | f <- files, f /= "." && f /= ".." ]
                            tell ["Directory: " ++ x]
                            else do
                                put xs
                                tell ["File: " ++ x]
                        walk
                    _  -> return ()

    たぶん、似たようなことをしているかと思います。

    まとめ

    今日はGo言語が1.3がリリースされました。もう、心がぴょんぴょんしてきます。

    また、もっと簡単にかけるぜ!という方、もしくは、PHPやRubyなどに興味があり、
    Fusicで一緒に働いてみたいという方はこちら
    フォームからご応募くださいませ。

    それでは。

      はてなブックマーク - Sinatra+Mongo+Pusherで忘年会余興アプリを作ってみた
      このエントリーをはてなブックマークに追加

      こんにちわ、Fusic新卒のカワサキです。
      だいぶ投稿が遅れてしまいましたが、先日の忘年会2013のお話!

      10周年記念パーティーのときもそうでしたが、弊社ではなぜか行事ごとに力をいれていて、IT会社らしくITを使って何かやるというのが「仕来り」になってきています笑

      ということで今回も
      ・みんなが知っているゲーム
      ・ルールが単純
      ・チーム対抗で楽しめる
      を前提に幹事チームで考えた結果、アタッ○25「っぽい」ゲームをやってみましたw

      1545777_707721675929493_1789192938_n

      943057_707722552596072_1538389287_n

      1512660_707724779262516_29234952_n

      使用した技術

      Pusher(pusher.com): 早押しボタンなどのリアルタイム通信のため
      Sinatra: Pusherのサーバ側、Publishや認証のため
      MongoDB: パネルの状態保持のため
      Grunt: CoffeescriptとかLessのコンパイル自動化のため

      今回はPusherにリアルタイム通信周りを「おまかせ」したおかげで、ほとんどサーバサイドが必要なく、Html・CSS・Javascriptのクライアントサイドアプリになったかなという感じ。
      なのでRubyは最低限必要部分だけで、メインはSinatraのpublicディレクトリにGruntでクライアントサイド開発をしやすい環境整えて、開発していきました。

      実際Pusherのおかげでリアルタイム通信部分はほんとに少ないコードで書けて
      ・Sinatra側でPublish用のメソッドを用意
      ・JS側でチャンネル・イベントのバインドとAjaxでのデータPOST
      だけで、簡単にリアルタイム通信を行うことができました!

      例えば、早押しボタンを例にすると

      Sinatra側のPublishメソッド

      1
      2
      3
      4
      5
      6
      
      # server.rb
      post '/pusher/publish' do
        Pusher.trigger('channel-name', params[:event],
          params[:contents]
        )
      end

      Ajaxで早押ししたチーム色のPOST

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      # buzzer.coffee
      $('#buzzer').on 'click', 'a', ()->
        $(@).attr('href', "##{color}")
       
        $.ajax
          type: 'POST'
          url: '/pusher/publish'
          data:
            event: 'attack:buzzer'
            contents:
              color: color

      早押ししたチーム色の音をならす・一番早かったチーム以外受け付けない排他制御・回答者を点滅

      1
      2
      3
      4
      5
      6
      7
      8
      
      # panel.coffee
      channel.bind 'attack:buzzer', (data)->
        return if fastest
        fastest = data.color
       
        playPlay('panel-' + fastest) #早押ししたチーム色の音をplay
       
        flashOn(fastest) # 回答者点滅

      のような感じで、簡単にリアルタイム通信を行えます。

      また幹事チームの役割分担もけっこううまくできて

      上司W: 当日の進行・景品の準備・音源の獲得。
      上司O: パネル画面の実装・映像問題作成。
      : サーバ側・早押しボタン・ポイント画面の実装。

      といった感じで役割分担し、全体の構成や問題についてはみんなで話し合って進めていきました。

      あと今回最後の映像問題の答えが「黒田官兵衛」だったので、昼休みにわざわざ福岡城に撮影しにいったり、先輩たちに「無理やり」筑紫もち早食いさせられたりと、良い?思い出があったりしますw

      当日もよりリアルな雰囲気を再現するため、幹事はコスプレしたのですが、なぜか白髪のおじさんじゃなくて「バーコードハゲ」だったり、アナウンサーではなく「女子高生」だったり、なぜかなぜか「お地蔵さん」がいたりとなかなか面白かったです笑

      1536716_707720409262953_1660490088_n

      感想やまとめ

      ・当日は思った以上にみんなが真剣にクイズとか考えてくれたし、盛り上がってよかった。
      ・無駄にアタッ○25に詳しくなった。例えばパネルがめくれる際の音は赤・白・青・緑、全ての色で違うとかw
      ・幹事チームのメンバーは普段案件とかであまり関わりがなかったので、短い期間ですががっつり絡めてよかった。
      ・普段業務で使ったことがなかった技術、今回でいえばPusherやGruntなど使えて勉強になった。

      以上、次回の行事ごとにも期待です!

      { 2013.7.29 }

      LambdaとTryと私

        はてなブックマーク - LambdaとTryと私
        このエントリーをはてなブックマークに追加

        こんにちは、Fusicの中野です。
        Ruby on Rails(ActiveSupport) にObject#tryという便利なメソッドがあります。

        1
        2
        3
        4
        5
        
        a = { b: 1}
        a.try(:[], :b) # => 1
         
        a = nil
        a.try(:[], :b) # => nil

        で、便利なのでついついこんな感じで書いてしまいます。

        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
        
        class Tables < ActiveRecord::Migration
          def up 
            create_table :as do |t|
              t.text :title
              t.timestamps
            end
            create_table :bs do |t|
              t.text :title
              t.integer :a_id
              t.timestamps
            end
            create_table :cs do |t|
              t.text :title
              t.integer :b_id
              t.timestamps
            end
            a = A.new(title: "title")
            a.bs << B.new(title: "title1-1"); a.bs << B.new(title: "title1-2")
            a.bs[0].cs << C.new(title: "title1-1-1"); a.bs[0].cs << C.new(title: "title1-1-2"); a.bs[0].cs << C.new(title: "title1-1-3")
            a.bs[1].cs << C.new(title: "title1-2-1")
            a.save
          end
          def down; drop_table :as; drop_table :bs; drop_table :cs; end
        end
         
        # ↑のようなデータがあったとして
         
        c = C.find_by_id(1)
        c.try(:b).try(:a).try(:title).try { |_| "#{_} == title" } # => "title == title"

        なんかかっこ悪いので、こちらの素敵なライブラリを使ってみましょう。

        1
        2
        3
        4
        5
        6
        7
        
        require &#039;lambda_driver&#039;
         
        c = C.find_by_id(1)
        (-:try < c).(&:b >> :a >> :title >> lambda { |_| "#{_} == title" }) # => "title == title"
         
        c = C.find_by_id(10)
        (-:try < c).(&:b >> :a >> :title >> lambda { |_| "#{_} == title" }) # => nil

        すごく、ナウいですね。

        最後に

        最近、このブログがPHPばかりだったので、なんとなくRubyの記事を載せてみました。
        決して社内研修の次の日なので、疲れているとかではありません。