Swiftのクラスメソッドの中でクラス定数を使う

私もちゃんと理解してないんだけど、メモ用。Swift限定の仕様じゃないかもしれない。

変なとこあったらご指摘ください。

 

Swiftのクラスメソッド(SwiftではType Methodかな)の中でクラス定数を使おうとした。

Objective-C

#define TEST_VALUE 1

@implementation TestClass

みたいになってるクラスを書き換えたかったのでやってみると、コンパイルエラーで止められる。。。

class ClassHasInstanceMethod {
    
    let testValue:Int = 1
    class let testValue2:Int = 1 // Error! Class variables not yet supported
    
    func getValue() -> Int{
        return testValue
    }
    
    class func getValue2() -> Int{
        return testValue // Error! 'ClassHasInstanceMethod.Type' does not have a member named 'testValue'
    }
}

var instance = ClassHasInstanceMethod()
println(instance.getValue())  // 1

not yet supportedってなんなんだって話なのですが、とりあえず使えない。

あとちゃんと定義してるのにdoes not have a memberって言われてさらに腑に落ちない。

(ちなみにjavaっぽくstaticもつけてみたけど、static letはだめっぽい)

 

結局いろいろ試行錯誤したら、下のようにするとどうにか動いた。

private let testValue:Int = 1 // Define constant out of class
class ClassHasTypeMethod {
    
    class func getValue() -> Int{
        return testValue
    }
}

println(ClassHasTypeMethod.getValue())  // 1

class宣言の外で定数を定義すると、そのファイル内で使える定数になるみたい

(他のクラスから使わないようにするならprivateをつける。)

 

そういわれてみればObj-Cの#defineも@implementationの前でやってるし、これが普通なのか・・・?

パリで働き始めました

f:id:Sato_4tree:20140805045446j:plain

photo:会社から見える時計の建物。20:30でこの明るさ

 

2週間ほど前からパリで働き始めました。

日々色々いっぱいいっぱいで全然ブログかけてませんでしたが、生活はどうにか慣れてきた気がします。

 

仕事は..

( ´△` )。՞。゚՞

久々に全てがわからないみたいな状況に直面すると混乱して泡吹きそうになりますね。。。ぶくぶく

でも相当な助けを毎日頂いて、どうにかこうにかやってます。

パリの人たちは想像してたように定時ぴったりにみんな帰るとかではなく、意外と普通に働きますw

でも20:30になったらすっかり最後の一人になってました。

 

システム的話をすると、深夜対応とかはないしモバPもないです。

会社をでたら完全にプライベートの時間なので、恋人や家族のために使えってことみたいです。

ちゃんとunit / integration testの自動化しておけば、そんなアプリ起因でシステムとまったりすることないだろって言われました(ごめんなさい)

Test Engineerが各チーム必ずひとりずついて、BDD(ビヘイビア駆動開発)で進めてるようです。余りこのへんまだ詳しくないですが。
(逆にこういうの整えてからじゃないとアジャイルやるの難しいんじゃないかっていうのが最近感じてること)

 

ごはん。フランス人は昼はバケットサンド、夜はフレンチフルコースゆ~っくり味わって食べるイメージでしたが

昼から結構ガッツリだべるし、日本だとかなり食べるの早い私より全然食べるのはやくてびっくり。私もそのうちそのスピードに慣れていきそうだけど。。。

逆に夜の飲み会はひたすら飲むだけで、食べません!食べ物出てきません。衝撃。

ワインだけグビグビ飲んでたら酔うよ・・・!

ただ、なんかお菓子の差し入れとかがやたら多いのであんまり痩せる気はせず、

むしろ最近はチームメンバーにまで「お前体重大丈夫か?」っぽいこと言われる日々です、あれ・・・?

 

挨拶。握手する挨拶もよくやりますが、

ビズという、ほっぺとほっぺをくっつけて「チュッチュ」って音だけならす挨拶をします。挨拶チュッチュ。

これがフランス人のあいさつ、“ビズ”だ!

聞いてはいたものの、久々に会った時とかだけにやるのかと思ったら

普通に毎日握手やらビズやらするから衝撃・・・!

男性とやるとひげがあたってたまに痛いです。

一人ひとりにビズして回ってる女性とかもいて、日本なら(*´Д`)ハァハァする人が出てくることでしょう

 

あとなんか知らないけどリア充多いですw

フランス人はプライベートの話をしないって聞いてきたけど、むしろ日本より全然オープンで、すぐboyfriend / girlfriend の話が出てきます

会社の飲み会で普通にみんながいる前でチュッチュしてる同僚がいた時の衝撃たるや(挨拶じゃなくてガチ)*1

 

 

日々発見の毎日、あっという間に一日が終わっていきますが、

色々なこと吸収して頑張っていきます!

À bientôt!!

*1:これはフランス人からしてもやり過ぎな例らしい

Git / GitFlowをチームに導入してよかったこと・よくなかったこと

チーム向けにgit-flowの勉強会をやってみた。

ちょうどいい機会なので、それまで使っていたCVSと比較しながら、

チームにGit/GitFlowを導入してよかったこと、よくなかったことを書いてみる。

状況

うちのチームは1年前くらいにそれまで使っていたCVSを脱して、Gitに全てのリポジトリを移した。

皆にGitにしたいって強いモチベーションがあったわけではなく、CVSが近いうち使えなくなるからということで、半ば強制的に移行した。

長期にわたるリリースが多いので、GitFlowブランチモデルを使ってる。

Git / GitFlowをチームに導入してよかったこと

Pull Requestでレビューがすごく楽

CVS時代はReviewBoardというレビューツールを使ってた。

ReviewBoardも左右のファイルのdiffを見てレビュー出来る点で結構いいツールだったけど、

diffを見るためには自分で変更した後diffファイル作って、それをアップロードして。。。となかなか手間がかかった。

さらに変更ファイル数が多いとアップロードしきれず、わざわざ一つの変更を複数のレビューに分けるとか変な工夫を強いられていた。

 

Gitで(というかGitの管理ツールで)Pull Requestを使うと、commitしたら勝手に変更がレビューに反映されるので、diffファイル作る手間がない。

また、Pull Reqest上にcommit logが出るので、誰がどの変更をしてどの状態になったかすぐわかる。

Pull Requestはこれなかったらもう開発できないレベルになったと思う。

Repositoryごとにバージョン管理を行うからマージ漏れが減る

CVSはファイルごとにcommitを行い、ファイルごとにバージョンを持っていたので、

変更履歴が一覧で見れないし、全部のファイルがブランチからHEADにマージされたか確認するのもだいぶ苦労してた。

 

Gitはリポジトリごとにバージョン管理しているので、そのリポジトリに対するコミットログが一目でわかるし、

ブランチをマージする際もそこまで負担がない。

今のアクティブブランチがすぐ見れる

CVS時代、何年も積み重なったブランチとタグがあり、

現在のアクティブブランチを確認するのは後述するExcelブランチ絵を見るしか方法がなかった。

さらに、ブランチを切るときは全体にメールするっていう謎の運用があった。

 

GitHubなどの管理システムでは、現在切られているブランチをすぐ確認することができる。

リリースが終わったブランチは削除するという運用にすれば、

現在切られているブランチは全てアクティブブランチということになる。(ここの運用は自分たちでやる必要があるけれど。)

今のアクティブブランチさえわかれば、今どんなプロジェクトが進んでいるのかだいたいわかるし

ブランチを切ったことを全体にメールするなんてことはもちろん必要なくなった。

コミットグラフ(ブランチ絵)*1の管理をしなくて良くなった

CVS時代は、それはそれは長く成長したExcelファイルを相手に、コミットグラフを自分たちで描いていた。

Excelなので、誰かが編集中だから今は書けないとか、共有ファイルサーバの容量がいっぱいで今は保存できないとか

辛く厳しい戦いを強いられながら、私達はExcelファイルを編集していた。

 

まず、Gitは前述したようにアクティブブランチが常に見れる状態なので、ブランチ絵をそもそもそんなに厳重に管理しなくても良くなった。

さらにブランチ絵を見たい場合は、うちのチームは余りまだ活用しきれてないんだけど、SourceTreeやgitkなどのツールを使うと

特に何もせずとも自分の作業のブランチ絵が見れる。

f:id:Sato_4tree:20140714234112p:plain

releaseブランチの時点で1度マージできる

これはGitFlowについて。

CVS時代、ブランチをHEADにマージするとなるとそれはそれは一大事だった。

リリース直前に他のマージされたブランチの差分を見ながらデグレって無いか確認しつつ、

半日くらいかけてCVSのいろんなオプションを駆使してdiff確認してマージを行っていた。

 

git-flowを使うとreleaseの時点で他のブランチがdevelopに入れた変更をマージすることができる。

releaseブランチでQAやリハーサル環境でのテストをやるようにすれば

他のブランチの変更が入った状態でテストを行うことが出来るので、デグレなどのリスクが減る。

さらにリリース直前じゃなくQAの前段階で1回マージできる安心感もある。何かバグがあればreleaseで直せるので。

releaseやhotfixからタグを自動で付けることができる

これもGitFlow.

CVS時代、(これはうち特有だけど)マージ時などににまたこれはこれは色んなタグを付与していた。

ブランチ切った時点のタグ、HEADマージ前タグ、HEADマージ後タグ、ブランチ側マージ前タグ、リリースタグ...etc

CVSの時は1ファイルだけHEADを直更新するとか、ブランチからブランチへマージ、みたいなことをちょくちょくやっていたので

実際これらのタグはdiffなどを確認するとき必要であった。

git-flowコマンドを使うと、 releaseやhotfixを切るときにタグ番号を指定することになり、

さらにreleaseやhotfix→masterへマージするときに自動的にタグ番号が追加される。

masterへの更新はこの2ブランチからのマージでしか起こらないので、タグの管理もシンプルなものになる。

実際CVS時代あんなに使っていたタグも、GitFlowに従うようにしたらこのシンプルなタグ番号のみで十分事足りるようになった。

困ったらググれば色々でてくる

CVSはもうかなり昔のサービスなので、ググってもなかなか情報がありません。

Gitは困ったらすぐ情報が出てくる出てくる!!

git add, commit, pushを取り消す方法やら、git-flowの使い方やら、困ったらgoogle先生に聞けば大抵のことは教えてくれます。

Git / GitFlowをチームに導入してよくなかったこと

学習コストがかかる

これはGitに限らずなんにでも言えることだけど、学習コストはそれなりにかかる。CVSとはかなり異なるコマンド使うのでなおさら。

さらにGitFlowの話になると複雑になって、「こんな複雑なのすぐ廃れるだろ」とか「なんでこんなことやるんだ」とか色々言われたりする。

だけど、そこでくじけずリポジトリ移しちゃえば強制的にGit使うようになるし、その後色々楽になるはずなので、皆様頑張って導入していただきたいですmm

GitFlowの流れが複雑でマージミスがよく起こる

ほんとこれに限るなと。

GitFlowはmaster, develop, feature, release, hotfixという5種類のブランチを使いながら開発していくやり方であり、

どこからどこへマージするべき、というのも明確に上の図のように定められているのですが、これを覚えるのはなかなか大変。

それでもgit-flowコマンドを使っていればミスが起こることはほぼないのですが、全員には浸透しきっていないようで

間違ってまだリリースするべきでない内容がfeature→masterにマージされるみたいなことが何度か起こった。

このへんは気づかないと大惨事だし、気づいてgit resetgit push -fなどを駆使して修正するのは特定の人だけになるので

こういうGitトラブルシューティングに工数を割かれている部分がある。

(Gitトラブルシューティング力はもっといろんな人に広めないといけない。。。)

GitFlowの流れが複雑で無理やりマージもよく起こる

CVSの時は、1行だけ設定ファイルを変えたいときなど、1ファイルだけcheckoutして更新してHEADに直commitみたいなことができていたのだけど

GitFlowではmasterの直更新は不可なので、ほんの少しの更新でもhotfixブランチを切ってもらってマージすることになる。

それがめんどくさい、と感じるのもまあ当然ではあるので、

無理やりmasterだけ更新して、その内容をpull request使ってdevelop->masterにマージされたりみたいなこともちょくちょく起こる。

 

この両問題は、GitFlowの使い方を熟知してもらうこと、使うメリットをわかってもらうことが重要だと痛感。

まとめ

以上、Git/GitFlowをチームに導入してよかったこと、よくなかったことでした。

もちろん総合的に見れば良いこと尽くしですが、ちょっと難しいところもあったよというところで。

これからGit、GitFlow使い始める方はご参考にしていただけたらと思います。

*1:そういえばうちはコミットグラフをブランチ絵って言うのですが、社内用語だろうか。。。?

GitHub実践入門-Pull Requestによる開発の変革- スピード感想

f:id:Sato_4tree:20140710224045j:plain

昨日、弊社の社内勉強会にGitHub実践入門の著者である @HIROCASTER さんにお越しいただき、GitHub活用術の話をしていただきました。

さらにひょんな流れから、なんと「GitHub実践入門」の本まで頂いてしまった!

ありがとうございます!!ありがとうございます!!

 

まだ流し読みしかできていないのですが、スピード感想をここに。

心に残ったフレーズ
  • Pull Requestを育てる
  • GitHub単体だと、現在利用しているプロジェクト管理ツールよりも機能的に足りない点もあるかと思います。ですが、その足りない機能を一度捨ててみることも検討してください。GitHubのような非常にシンプルな機能だけで、ソフトウェア開発は十分にできるはずです(Issueとかの話)
  • 常にデプロイ。リリースという概念はない(GitHub Flowの話)
  • すべての変更をステージング環境で確認してからデプロイするのはナンセンスです(GitHub Flowの話2)

下2つはあまりに自分の環境と違いすぎてうおおと。

GitHub Flowは、開発者が主体になってるサービスで、自由に変更をリリース(デプロイ)できる人達が使うものだと確認。。。。
やっぱしばらくgit flowを使っていくことになりそう

ただシンプルがベストっていうのはこの本でも昨日のお話でも強く主張されてたところだった

GitHubが(特に弊社で使用しているStashと比べて)面白いなあと思ったこと
  • : って入れると絵文字の補完機能がある。円滑で素敵なコミュニケーションに
  • ブランチ絵デフォで見れる
  • "fix #24"とかcommitコメントに書くと勝手にIssueをcloseしてくれる(ただこの機能はぶっちゃけいらないw)
  • Pull Requestでチェックボックスのタスクリストかける
  • hubコマンドが長くなりがちなgitのコマンド簡略化してくれて便利

このレビューが終わったら1杯引っ掛けようやって気持ちをここに

f:id:Sato_4tree:20140710225645p:plain

やりたいなと思ったこと
  • WIP Pull Request (Work In Progress Pull Request)
    • [WIP]*** function addition みたいに、Pull Requestの先頭に[WIP]ってつけることで、そのコードがまだ開発中だよってことを表す
    • コードが完成してからでなく開発中の時点でPull Requestを送っておく
    • そうすることでいきなり大量のソースをレビューになってから見ることはなくなるし、開発中にPull Request上で議論することも出来る
  • commit単位を小さく。あ、ついでにここも治そうっていうのがあったら、それはcommitを分ける!
    • Pull Requestでレビューする人から見て、このためのにここを直したっていうのがわかりやすくなる

この2点が簡単に取り入れられそうで、効果もありそうなので、周りに広めていきたい

Pull Requestは今でも使ってるものの、「レビューは時間あるときね」「見る時間ないから自分たちでレビューしておいて」みたいなレビューに対する障壁はまだまだ感じているので、薄くなっていくといいなあ

本を通して
  • ネタバレになっちゃいますが、はじめてのPull Requestの練習ということで、
    この本の感想ページがかかれたリポジトリを実際にforkしてきてにPull Request->Webページに反映させるという企画があって、
    それがすごいオープンソースな感じで感動した。ほんとGitHubだから出来る

  • @naoya_ito さんもTwitterで言っていましたが、単なるgitとgithub利用方法だけでなく、かなり活用方法に触れてたのが良かった。特に9章の開発フローのところはすごく参考になった

以上、流し読みですがスピード感想でした。

これからもっとじっくり読んで咀嚼していきたいと思います。

P.S.

Ship It Squirrel and the Update the Plan Elephant - Geoffrey Wiseman

f:id:Sato_4tree:20140710232746p:plain

結局なんでリスがShip itなのか謎。。。リスのように軽快に開発すべしってことなのでしょうか。

誰か教えてください

フランスのビジネスマナー

France - Geert Hofstede

今日、フランスで半年ほど仕事をしたことがあるというキャリアウーマンの女性からフランスのビジネスマナーについて教えてもらった。

それがかなり日本やアメリカのイメージと違っていて驚いたことが多かったので、覚えてることを箇条書きで書いていく。

注)あくまでその人がフランスで働いていた時に感じたことなので、企業文化、個人、その他によって大きく異なる可能性があります。

  • 業務時間中はかなりストイックに働き、業務終了時刻になったらさっと帰ってPrivate timeを大事にする
  • 逆に業務時間中は時間を一切無駄にできず超集中してるので、昼休み中にお昼寝してる人などはひとりもいない
  • 仕事の場面やメールでは、相手に敬意を示してFamiry Nameで呼ぶ。ムッシュTanaka、マダムTanakaなど(アメリカとかむしろFirst Nameで呼ぶイメージなのに!)
  • 書き言葉でFamily Nameを大文字で表すのは敬意の証。 Taro TANAKA みたいな
  • 「かわいい」女性は求められない。「エレガンス」な態度で振る舞う女性が好まれる(((((( ゚д゚))))))
  • お酒はワイン。ビールを飲む女性は余り好まれない。ただし酔っ払うのもかなり失礼なので、飲み過ぎないように
  • 家族の話など個人的な質問はしない
  • 握手はとっても大事な挨拶(儀式?)なので気をつける。相手の目を見て少し強めに握って3シェイク
  • ただ相手の家に招いていただいたらそれは最大級の受け入れの証なので、絶対に行くこと
  • 会社の中でのヒエラルキーはかなり強い。偉い人に自分から話しかけたりせず必ず間を通すこと
  • MTGに出る際の座る椅子の位置も重要。小さいチームなら予めおきまりの場所があるかもしれないので、必ず最初のMTGではどこに座っていいか聞くこと
  • MTGとかレストランに早く行き過ぎるのはNG!ピッタリかちょっと遅めに行くこと
  • MTGは意思決定をするためのものであり、情報共有だけのMTGなどはない。
  • 食事の席で髪をいじるとか鼻をすするとか絶対ダメ!やりたいならトイレで。鼻は後ろに無いてティッシュでささっと噛むでもOK
  • 誰かが休んでいたとしても、その人の仕事を代わりにやってしまうとその人が必要ないとみなされるから、絶対やっちゃいけない。
    ex)タスクを自分に振る予定だったマネージャーが休んだとき、周りの人に何かタスクを降ってくださいと頼んでも、上司の仕事を取ることになるので振ってくれない。そういう時はおとなしく机で本とか読んでた方がいい。

 

日本に帰ってくる頃にはスーパーエレガントな女性になっていたい所存でございます

フランス大使館に研修ビザの申請に行ってきた

2週間後から会社の研修で5ヶ月ほどパリに行かせていただくことになったので、

研修ビザの取得のため、フランス大使館にビザの申請に行ってきました。

あまりネットに情報がなかったので、これから申請する人の何かの足しになれば:)

f:id:Sato_4tree:20140705140820j:plain

ビザの申請書類等の手続きを頼んでいる方からは「フランス大使館での大使館面接」って言われてたのでドキドキしてたのですが

研修ビザの場合、実際にやることは必要書類の提出とビザの申請だけでした。

一応ジャケット着ていったのですが特に意味なかった。。。

申請料金支払いのところでBonjour!ってあいさつされるのBonjour!って返しましょう。その後は日本語ですw

 

ビザにはいろいろな種類があるのですが、私が貰いたいのは長期滞在ビザの中の一つ「社会人の研修生ビザ」

社会人の研修生ビザ - La France au Japon

発給されるビザは有効期限が3ヶ月のものとなりますが、フランス入国後2ヶ月以内に滞在許可証を申請すれば、期間を伸ばすことができるそうです。

 

ビザ申請に必要な書類は以下のとおり。

社会人の研修生ビザ申請 申請書類チェックリスト(pdf)

また、申請からビザの発行までは、必要書類に不備がなければ1週間ほどだそうです。    

ビザの申請はこちらのサイトから予約が必要です(私の場合は業者の方にやってもらいました)

ビザ申請予約システム - La France au Japon

アメリカかどこかの大使館は、混みすぎて会館前に行っても○時間待ち という話を聞いたことありましたが

少なくともフランス大使館は予約した時間にちゃんと行けば特に問題なかったです。

 

「必要書類の提出とビザの申請だけ」と言いましたが、ここで若干注意しないとやり直しになるので、注意ポイントをいくつか。
(わたしも1回「確認しなおしてから来てくださいー」ってなった)

  • 研修協定書は労働局からの承認を受けているもので、その場で修正できないので、
    予め研修開始日/終了日とかの情報に誤りがないか確認しておく。
  • 研修協定書は大使館側にはコピーを提出するので問題ないので、原本は手元にとっておく。
  • パスポートはコピーと原本両方持ってったほうが良さそうだった
  • その他の書類も全てコピーをとっておく or pdfなどにしてあとから参照できるようにしておく
  • ビザ申請書は業者の人に書いてもらってたりするとパッと見全部埋まってるように見えるけど、
    埋まってないところがあったりするので、申請書の日本語訳見ながら確認する
  • 給料が元の自分の会社から出るのか研修先企業から出るのか確認しておく(口頭で聞かれた)

申請の窓口の方は最初ちょっと怖いですがちゃんと話すととても親切な方でした。注意されたら素直に従いましょうw

 

ビザの申請が終わったら、進捗状況をこちらから確認できるようです。

Visa application status check - InfoVISA

私の場合昨日申請したのですが、"Your visa application is still being processed."ってでてました。シンプルな情報ですw

 

無事に発行されますように!

gitでまだマージしたくない変更を間違ってmasterにマージしてしまった時の対処

久々にgitですごい躓いたので。

説明すると、branch02の内容を謝ってmasterにマージしてしまった後、それに気づかずbranch01の内容もmasterにマージしてしまった。

あとから気づいたので、branch02の内容だけmasterから取り除いて、もろもろレビューが終わってからbranch02の内容はmasterにマージしたい。

言葉で説明すると意味不明なので図*1がこちら

https://cacoo.com/diagrams/0CU2tMOnYkDhU7ct-F5B95.png

commitを取り消すコマンドはgit resetが有名だけど、git resetはあるcommit時点まで戻り、それ以降のcommitをなかったことにするというものなので、branch01のcommit内容も消されてしまう。(まあ戻そうと思えば戻せる)

そこでまず使うのがgit revert

git revert {commit No}

Git チュートリアル: 変更を元に戻す | アトラシアン

これで、「ある特定のcommit内容を取り消す」というcommitを行うことが出来る(git resetと違って本当になかったことにされるわけじゃない)

f:id:Sato_4tree:20140630222625p:plain

ここまではOK。

 

そのあとbranch02のレビューが完了したので、ここで再びbranch02をマージしてみる。

これがbranch02→masterへの変更内容。running.txtの2行目に文章を追加してます。

f:id:Sato_4tree:20140630223142p:plain

で、branch02→masterへのマージが完了したところで、masterのrunning.txtを見てみると。。。

f:id:Sato_4tree:20140630223707p:plain

あれ!?変更が反映されていない!???

実は、先ほどgit revertでbranch02のcommit内容を取り消しする、というcommitをしてしまったため、

その後branch02をmasterにマージしても、そのcommit内容は取り消されてしまうのです!

ここでbranch02→masterへのマージができなくなり、だいぶつまづく。。。

四苦八苦した結果、1回masterのrevertしたって内容もbranch02にmergeしてくればいいのではないか?と思いつく

git checkout branch02
# master→branch02にマージ
git merge master

この状態だとbranch02の変更内容が消えてしまってるので、revertする前のcommit情報を持ってくる(あとに追記あり)

# 特定のファイルだけrevert前に戻す
git checkout {revert直前のcommit No} {戻したいfile name}
# ex : git checkout c6881bf28944f3d8c779e26a9a004b14a44d230c running.txt
git add running.txt
git commit -m "re-commit running"

最後に、masterにマージすると・・・

git checkout master
# branch02→masterにマージ
git merge branch02
git push origin master

f:id:Sato_4tree:20140630235408p:plain

できたー!!

マージ間違いには注意しましょうmm

 

2014.07.01 追記

FaceBookで「revertのrevertすればいい」という意見をもらい、うまく行ったので追記。

git checkout branch02
# master→branch02にマージ
git merge master

# さっきrevertしたcommitをさらにrevertする(取り消しの取り消し)
git revert {revertのcommit No}

git checkout master
# branch02→masterにマージ
git merge branch02
git push origin master

これでもうまくいきます。こっちのほうが簡単ですね。ありがとうございますmm

*1:図を書くのにCacooってサービスが使えると聞いて使ってみた。なるほど確かに便利