Ruby

2020/03/06

Ruby初心者が間違いそうなこと

Ruby初心者が間違いそうなことの記事に共感したのでメモ。
適当なラフなメモ書き。

【参考】
Ruby初心者が失敗しがち/間違えがちなこと5選 | Workship MAGAZINE(ワークシップマガジン)

1. 範囲演算子の範囲を読み違えがち
=> 範囲演算子「..」「...」は異なる。点一つで意味は全く違う。

2. 引数にProcをそのまま渡しがち
=> Procをブロック引数として渡すために、&演算子を使う。
  さらに、シンボルで渡す方が簡略化できる。
  injectが良い例。
  &演算子を使う部分はPerlに似ている。

3. Array#mapのブロック引数で、途中結果を返却するためにreturnを書きがち
=> mapやselectなど、ブロック引数を受けとるタイプのメソッドを使用する際、「ブロックの途中で得られた値」を「そのブロックで得られた最終結果」として返却したい場合では、「return」ではなく「next」を使う。
結構間違える。

4. 正規表現のマッチ結果を思うように取得できない
=> ()でグループ化した正規表現に対し、組込変数$1,$2...に、マッチング結果が格納される。
 Perlと同じ。Javaとは異なる。Javaの方が面倒。

5. privateなクラスメソッドを定義しようとしてpublicにしがち
=>
 privateの考え方はJavaやC#と全く異なるので、最初は混同してた。

JavaやC#の常識が通用しないRubyのprivateメソッド - give IT a try

[Ruby] privateメソッドの本質とそれを理解するメリット - Qiita

Javaならば、親クラスのprivateメソッドは子クラスでは呼び出せない。
しかし、Rubyでは「privateメソッドはサブクラスからも呼び出せる」考え方が最初は分かってなかった。
「privateメソッドは呼び出す際にレシーバを指定できない」「子クラスでは、親クラスのメソッドをレシーバ無しで呼び出せる」ことを組み合わせれば良い、という記事を読んでようやく理解できた。

6. スコープゲートが厳しい
=> Rubyのスコープゲートは厳しい。
 Rubyは、class、module、defのスコープゲートは乗り越えられない。

ローカル変数をスコープ内側へ - 【旧】PerlerのRuby日記->はてなブログに移行しました

 Perlは、myを付けなければ、ローカル変数はメソッド内でも使える。
 Javaならば、クラス内ではprivateな変数はどのメソッドでも使える。
 この点をよく間違えていた。

 一方、Rubyでは、ブロックならスコープゲートを越えられる。
 たとえば、define_method do~end、Class.new do~endのような書き方でスコープゲートを回避する。
 つまり、フラットスコープ。

| | コメント (0)

2020/02/24

メタプログラミングRubyの感想

「メタプログラミングRuby 」を一通り読み終えた。
まだ全ては完全理解できていないが、やっとRubyの面白さを感じ取れた気がする。
理解したことをラフなメモ書き。
まだ初心者なので間違っていたら後で直す。

【参考】
メタプログラミングRuby - ククログ(2010-09-13)

メタプログラミングRubyを読んだ - razokulover publog

「メタプログラミングRuby」オススメです - UUUM攻殻機動隊(エンジニアブログ)

「メタプログラミングRuby」ことはじめ?開発本部・TechLunch? - Medley Developer Blog

【1】JavaやC#、VB等と違って、Rubyの特徴や面白さはどこにあるのだろうか?
「メタプログラミングRuby 」を読んで、自分はRubyの威力を完全に理解できていないことが分かった。
特徴は3つあると思う。

【2】一つは、ArrayやHash等の基本ライブラリが十分揃っていること。
VBはリストやハッシュのライブラリが貧弱で、ちょっとした操作にかなりの行数が必要になる。
JavaはArrayListやMapなどにはライブラリは揃っているが、Rubyほどないように思う。

Rubyならmap, collect, find, select, inject, reduceなど、配列やハッシュの単純な操作を短く書ける。
オープンクラスだから、後でいくらでも機能追加できる。

後から発展してきたプログラミング言語ほど、リストやハッシュのような基本的なデータ構造を扱う機能は豊富だ。
昔のプログラミング言語ほど、リストやハッシュの簡単な操作だけに色々考えさせられて疲れてしまう。
だからこそ、低いレイヤで考える部分が少なくなり、本来の機能のレイヤを考える方へ労力を費やせる。

【2】Rubyのオブジェクト指向はJavaとかなり違う。
Javaはクラス重視だが、Rubyはメソッドを重視しているように感じる。

Rubyと大クラス主義とダックタイピング、そして名前重要 - ゆとRubyist日記

つまり、Rubyはメソッドを実行するレシーバよりも、メソッドというインターフェイスを重視している。
Rubyでメタプログラミングを読んでいると、メソッドなのか変数なのか最初は判別できない時がある。
たとえば、シンボルを渡して、ブロックに変更して処理を実行させる、とか。
むしろ、わざわざそう書いているとしか思えない。

オブジェクト指向の技術としては、Javaでは継承や委譲くらいしかないが、Rubyには、incude, prepend, extend, refineなど色んな技法が多い。
Javaはオブジェクト指向言語と言いながら、実際のプログラムは手続き型言語の気持ちで書いてる。
手続きで書いていって、ソースが長くなったら、OOPの技術でリファクタリングする、みたいな感覚。

一方、Rubyでは、メソッド探索や継承チェーン、method_missingのように、常に継承関係を意識しながら書いている。
Rubyの方が複雑な機能をスマートに書ける場合が多いように思う。
RailsのValidationで、フック処理と特異メソッド(クラスメソッド)を上手く使いこなしている解説を「メタプログラミングRuby 」で読んで、なるほどと思った。

【3】Rubyのライブラリは、メタプログラミングに向いた機能が多い。
むしろ、すごく多すぎてやり過ぎなくらい。
class_eval, define_method, instance_evalくらいならまだ良かろうが、evalで文字列のプログラムを実行評価できるのはやり過ぎなくらい。コードインジェクションのリスクもある。

でも、そのおかげで、似たような操作で名前の違うメソッドを一括処理することで、プログラム行数を相当短くできる。
たとえば、メソッドを文字列でGrepして、ヒットしたらある処理、ヒットしなかったら、ゴーストメソッドでmethod_missingで一括処理、とか。

また、Rubyでは、privateメソッドも外部から自由に扱えてしまうので、テストコードが書きやすいはず。
JUnitもリフレクションを多用しまくっていたし。
たぶん、Rubyの方が自動テストに向いているのだろうと思う。

一方、JavaやC#でメタプログラミングっぽいことをやろうとしたら、XML地獄になる。
XMLを書いている時間の方が長いくらいだ。
つまり、Javaは外部DSL、Rubyは内部DSLが扱える、ということなのだろう。
その分、Rubyだけで全て書ききれるから、ストレスも低いと思う。

そういう設計思想の元で、「メタプログラミングRuby 」では、Rubyは進化的設計に向いている、という解説があり、なるほどと思った。
たとえば、RailsのライブラリもVer1.0からVer4までVerUpするたびに、メタプログラミングで書いた部分をオブジェクト指向で書き直したり、method_missingを多用して性能悪化した部分を性能改善していくなど、色んな手間がかかっている。
そういう進化的設計は、アジャイル開発と相性が良い。
最初はまず機能をリリースして、ユーザに使える機能を提供し、VerUpするたびに機能を改善したり、性能を改善していく、というやり方だ。
そういう開発スタイルは、開発プロセスがフレームワークとして運用できるだけでなく、ソフトウェア開発技術そのものもレベルが高くなければ、コントロールできない。

つまり、Rubyはメタプログラミングとオブジェクト指向という2つの技術を使いこなすことで、適用できる場面をスムーズに変えることができ、スピード感のある開発と柔軟な開発という相反する手法をコントロールできているのだろう、と思った。


| | コメント (0)

2020/02/14

SmalltalkとLispから来たメソッドmap と collect、reduce と inject


SmalltalkとLispから来たメソッドmap と collect、reduce と injectをメモ。

【参考】
map と collect、reduce と inject ―― 名前の違いに見る発想の違い

【Ruby】
[3, 4, 5, 6].map {|i| i + 1 }
=> [4, 5, 6, 7]

【Lisp】
(map 'list (lambda (i) (+ i 1)) '(3 4 5 6))

【Ruby】
[3, 4, 5, 6].collect {|i| i + 1 }
=> [4, 5, 6, 7]

【Smalltalk】
#(3 4 5 6) collect: [:i | i + 1 ]

【Ruby】
[3, 4, 5, 6].reduce {|i, j| i + j }
[3, 4, 5, 6].reduce(:+)
=> 18

【Lisp】
(reduce (lambda (i j) (+ i j)) '(3 4 5 6))
(reduce '+ '(3 4 5 6))

【Ruby】
[3, 4, 5, 6].inject {|i, j| i + j }
[3, 4, 5, 6].inject(0) {|i, j| i + j }
[3, 4, 5, 6].inject(:+)
=> 18

【Smalltalk】
#(3 4 5 6) inject: 0 into: [:i :j | i + j ]

(引用開始)
map と collect の発想の違い
まずは map と collect の発想の違いを見てみましょう。
map
map は「データ構造を保ったまま3、あるルールに従って元のデータ構造を別データ構造に変換する」という発想になります。
(中略)
collect
collect は「データ構造内の全ての要素に対して、ある処理を繰り返し実行し、その結果を集めたもの」という発想になります。
(中略)
reduce と inject の発想の違い
次は、reduce と inject の発想の違いを見てみましょう。
reduce
reduce は「あるルールに従ってデータ構造内の要素数を縮小していき、最後に残った値を返す」という発想になります。
(中略)
inject
inject は「値をプールしておくバケツを用意しておき、データ構造内の全ての要素をひとつずつ、ある処理にしたがってバケツに注入していく」という発想になります。
(中略)
しかし別々の発想をしていても、それぞれで「こうした処理は必要だ」という結論になって、違う名前で同じ機能が実装されたということはとても面白いですね。実は今回取り上げた二つの機能、ひとつは「map と collect」が表現している「巨大なデータを構造を保ったまま別のデータに変換する」機能4、もうひとつは「reduce と inject」が表現している「巨大なデータのすべての要素を使って何らかの計算結果を求める」機能5は、巨大なデータを処理する場合の最も基本的な処理、つまり基礎となる機能なのです。
(中略)
5.数学ではこれを「畳み込み」と呼びます。
(引用終了)

mapはRuby初心者も慣れるが、injectの発想は面白い。
injectでは明示的にブロックを渡すのではなく、[3, 4, 5, 6].inject(:+) のように、メソッドのシンボルを渡すことで配列の要素に作用させる。

この辺りの考え方に、Rubyが過去の言語の良い所取りをしている感じがする。


| | コメント (0)

2020/02/06

Rubyのブロック、Proc、lambdaのメモ

Rubyのブロック、Proc、lambdaのメモ。

【参考】
Rubyの ブロック、Proc.new、lambdaの違い - Qiita

Rubyの「ブロック」を理解する - Qiita

Rubyの ブロック、Proc.new、lambdaの違い - Qiita

ブロックは処理の集合体。
ブロックはオブジェクトでない。
ArrayやHashのイテレータで慣れ親しんでいる。

メソッドがブロックを受け取る方法は2つ。
def hoge(引数) yiled end; では、hoge(引数){ブロック}で定義されているとみなす。
def hoge(a, &block) end; では、hoge(引数){ブロック}で定義されているとみなす。

ブロックをオブジェクトとしたものがProc.new。
lambdaはProcとほぼ同じように見えるが、lambda式を実行して返ってくるものはProcクラス。

Proc は引数チェックしないが、lambda は引数チェックするので、引数の個数が違うとArgumentErrorが発生する。


| | コメント (0)

2017/05/05

ソフトウェアの複雑性は本質的な性質であって偶有的なものではない

「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」を気軽に読んでいたら、ブルックスの人月の神話の一節が書かれていて、今頃になって、すごく腑に落ちたのでメモ。
ブルックスの人月の神話の文章のうち、自分が理解できたことを、ラフなメモ書き。
以下は書きかけ。

【参考】
第0回:人月の神話とはなんなのか?(解説編)|本気で読み解く”人月の神話” | GiXo Ltd.

第2回:銀の弾は無いけど、”銃”はあるよね|本気で読み解く”人月の神話”(第16章) | GiXo Ltd.

ソフトウェア開発とは、現実世界の複雑さをプログラムコードの難しさに置き換える作業だ - セカイノカタチ

ソフトウェア開発でよく言われる「銀の弾丸など無い」とはどういう意味なのか本を読んでみた。 - 感謝のプログラミング 10000時間

【1】ソフトウェアの複雑性は本質的な性質であって偶有的なものではない。

「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」の内容自体は10年以上前のWebやIT業界の話が多く、内容も古くなっているので、新たな知見が得られるという感覚はしない。
しかし、「過剰と破壊の経済学-「ムーアの法則」で何が変わるのか」の中に、「ソフトウェアの複雑性は本質的な性質であって偶有的なものではない」という言葉があって、すごくしびれた。

(引用開始)
ソフトウェアの複雑性は本質的な性質であって偶有的なものではない。
したがって、複雑性を取り去ったソフトウェアの実体の記述は、しばしばその本質も取り去ることになる。
数学や物理学は、複雑な現象を単純化したモデルを構成し、そのモデルからある性質を引き出し、実験的にその性質を証明することで、3世紀にわたって偉大な進歩を遂げた。
この方法でうまくいったのは、モデルで無視された複雑性が現象の本質的な性質ではなかったからだ。
複雑性が本質である場合には、この方法は使えない。
(引用終了)

上記の内容は、ブルックスの「人月の神話」の一節そのまま。
なぜ自分がすごく衝撃を受けたのか、考えてみると、ソフトウェア開発の本質に触れているものだから。
たぶん、僕の心のなかにある、ソフトウェアに対する楽しさだけでなく、ソフトウェアへの憎しみというか、なぜこう思い通りにソフトウェア開発をコントロール出来ないのか、という腹立たしさに触れている気がしたから。

「偶有的」という言葉も引っかかる。
この言葉は、古代ギリシャのアリストテレスの哲学から引用したものらしい。

(引用開始)
アリストテレスに従って、難しさを本質的なものと偶有的なものに分けて考えてみよう。
ここで、本質的な複雑さとは、ソフトウェアの性質に固有な困難のことであり、偶有的難しさとは、目下の生産にはつきまとうが本来備わっているものではない困難のことである。
(引用終了)

自然科学、特に数学や物理学では、できるだけ単純なモデルを作り、そこから演繹される性質や定理を証明することで、自然現象を多面的に分析しようとする。
複雑なものを複雑なまま捉えるのではなく、理想的な単純なモデルに純粋化して、人間の思考に耐えられるレベルにして、数多くの観点で徹底的に分析するのが自然科学のやり方。
シンプルなモデルを「徹底的に」分析し尽くして、全ての特徴を洗い出し、全てを因果関係や演繹でまとめ上げて一つの理論体系にするのが自然科学のやり方。

すると、シンプルなモデルをどのように事前設定するか、どのパラメータを重視して選択しておくか、というのが重要になる。
その部分が、科学者の腕の見せ所。

たとえば、物理学では、理想気体みたいに、現実から離れるけれど、シンプルなモデルを設定することで、計算や実験を扱いやすくするモデル作りは一般的だ。
熱力学、相対性理論、量子力学など、色んな分野の物理学でもその手法を用いている。

物理学は一つの認識論: プログラマの思索

数学でも、一流の数学者は、自分で理論を打ち立てたい時、最も組合せの少ない公理や公準を直感的に選んで、そこから矛盾が生じないように設定しておく。
そこから、「誰々の定理」のような重要な結果を導き出す。
一流の数学者がすごいのは、最も組合せの少ない公理を直感的に把握できること、そして、重要な定理を導く時に、ロジックの穴になりそうな難しい場所を事前に察知して、それをくぐり抜けるために、あらかじめ「誰々の補題」みたいな補助的な公式を用意しておくのが上手い点。

技術の背後に数学の理論があると廃れない: プログラマの思索

数学や物理は背景にある思想を知らなければ理解できない: プログラマの思索

このやり方がすごく成果を上げているので、人文科学や社会科学でもそのやり方を真似ているように思える。
特に、経済学は典型的だろう。
マクロ経済学やミクロ経済学みたいに、人間は合理的に行動する、とか、市場の価格は恣意的な手段で決めても長続きせず、神の手(つまりは市場原理)で決まる、みたいに、現実とかけ離れた仮定をおいて、数多くの経済モデルを作り、そこから重要な経済学の定理を導き出す。
単純な経済モデルから得られた経済学の定理で現実に通用する場面が過去にあったから、経済のグローバル化が世間に言われ始めてから、世の中の経済事象は、市場原理で決まる、いや決めるべきだ、みたいな論調が多い気がする。

経済数学の直観的方法の感想: プログラマの思索

「推計学のすすめ」「経済数学の直観的方法~確率統計編」の感想: プログラマの思索

しかし、ブルックスの「人月の神話」では、ソフトウェアにはそのやり方が通用しない、という指摘をしている。
「ソフトウェアの複雑性は本質的な性質であって偶有的なものではない」からだ。
つまり、複雑性を排除したソフトウェアは、ソフトウェアの本質を意味しないからだ。

【2】ソフトウェアの本質的な複雑さと、偶有的な複雑さの違いは何か?
ソフトウェアの本質的な複雑さは、リーマンの法則そのものを指すと思う。

リーマンの法則~ソフトウェアもエントロピー増大の法則を避けられない: プログラマの思索

リーマンの第1法則
 使われるシステムは変化する。
リーマンの第2法則
 進化するシステムは複雑性を減らす取り組みをしない限り、システムの複雑性が増す。
リーマンの第3法則
 システムの進化はフィードバックプロセスによって決まる。

(引用開始)
レーマンとベラディは、大規模なオペレーティングシステムのリリースについて、継続してその変遷を研究してきた。
そこで分かったことは、モジュールの総数はリリース番号とともに線形に増加するのに対し、影響を受けるモジュールの数はリリース番号に対し指数的に増加するということだ。
(中略)
システムプログラムの作成は、エントロピーを減らす仮定だから、本来は準安定なものである。
他方、プログラムメンテナンスはエントロピーが増加する過程であり、どんなに器用に行なっても、できるのはシステムが修正不能な陳腐化へと沈んでいくのを遅らせることだけである。
(引用終了)

(引用開始)
ソフトウェア製品開発に関する古典的問題の多くは、その本質的な複雑性と、ソフトウェアの大きさに従ってその複雑性が非線形に増大することに由来している。
(引用終了)

この文章を読んで思い出すのは、ケント・ベックがXPを生み出した経緯のことだ。
ケント・ベックは、ソフトウェア工学の授業で習った、リリース総数が増大するにつれてソフトウェアの複雑度や変更コストが増大していく経験則に対して、異議を唱えた。
時間が進むに連れて、この曲線を頭打ちにできるような開発プロセスはないのか、と。

- eXtreme Programmingの魅力を探る オブジェクト倶楽部

(引用開始)
「変化ヲ抱擁セヨ」
この呪文めいた言葉は,Kent Beck による本の副題として掲げられている. 時間を横軸に,ソフトウェアの変更にかかるコストを縦軸にプロットする.
この「時間-変更コスト」曲線は極端な右上がりになると信じられて来た(図左).
すなわち,要求分析,設計,実装,テスト,保守,と時間が進むにつれ, 変更にかかるコストが増大するというのだ.
現在までのソフトウェア開発プロセスは,この仮定上の議論が多数 だったのである.
XP はこの曲線を平坦にできるのではないか, また,そうできたとしたら,全く違った方針でプロジェクトに立ち 向かえるのではないか,という挑戦をしている(図右)
(引用終了)

こういう素朴な問題意識はすごく重要だと思う。
XPがその理想を本当に実現したのかどうか、は検証がいると思うが、そういう背景を元にアジャイル開発のプラクティスが生まれたことは、アジャイル開発が従来のソフトウェア工学と対立しがちに見える傾向を示唆しているように思える。

ちなみに、上記の第1版の「XPエクストリーム・プログラミング入門―ソフトウェア開発の究極の手法」に、上記の「従来のソフトウェア工学が提唱しているソフトウェア複雑性へのXPの果敢な挑戦」の文章と図はあるのに、第2版の「エクストリームプログラミング」から削られていることだ。
とても残念。
この部分がXPにとって一番重要な主張なのに。

【3】コードクローンと再利用性。

(引用開始)
ソフトウェア実体の本質とは、データセットやデータ項目間の関係、アルゴリズムや機能呼び出しなどが組み合わさったコンセプトで構成されたものである。
この本質は、同じ概念構造体が多くの異なる表現で表されるという点で抽象的である。
それにもかかわらず、非常に正確で十分に詳細なものである。
(引用終了)

コードクローンとは、同一アルゴリズムを各プログラマが別々の実装したプログラムのことだ。
上記は、ソフトウェアの複雑性が増大しがちな理由の一つは、コードクローンが大量に発生しがちである、と言う点を示唆していると思う。

ソフトウェア工学の論文を見ていると、コードクローンのメトリクス採取の記事が割と多い。
その理由は、コードクローンを減らす方がソフトウェアの複雑性が減るので、良い、という主張が隠れているのではないか。

では、なぜコードクローンは良くないのか?

(引用開始)
ソフトウェア実体は、どの2つの部分をとっても似ることがないので、大きさの割にはおそらく他のどの人工構造物よりも複雑なものだ。
似通っている部分があれば、2つの類似部分を1つにする。
この点において、ソフトウェアシステムは、重複要素(部品)が豊富なコンピュータやビルあるいは自動車などとは全く異なっている。
(引用終了)

その理由は、ソフトウェアの再利用が進まないからだ。
たとえば、自動車やパソコン、スマートフォンのような工業製品は、再利用可能な汎用部品を組み立てる手法と大量生産することを組合せることで、規模の経済を生かし、経験曲線効果を生かして、1個当りの製造コストを劇的に減らす。
しかし、この「規模の経済」「経験曲線効果」というコストメリットを享受しうる生産手法がソフトウェア開発には全くといっていいほど通用しない。

ソフトウェアを部品化して、スマートフォンみたいに部品を組み立てるように製造したい、と考えて、CORBAとかEJBのようなコンポーネント駆動開発、製品ファミリー群の製品開発手法であるソフトウェアプロダクトラインとか色々考えられたけれど、どれも実用的ではない。

ソフトウェア部品化の幻想: プログラマの思索

ソフトウェアプロダクトラインが解決しようとするもの~品質と再利用: プログラマの思索

だから、多額の資金を設備投資に投入して、最新の機械で汎用部品を組合せて大量生産する生産手法がソフトウェア開発には馴染まない。
ソフトウェア開発は徹頭徹尾、経験曲線効果すらも有効でない労働集約的な生産手法に似ているように思える。

【4】ソフトウェアの本質的な複雑性とは、同調性、可変性、不可視性。

【4-1】同調性は、リーマンの言う組み込まれた(Embeded)プログラム、を連想する。

「ソフトウェア・グラフィティ」の感想: プログラマの思索

(引用開始)
支配しなければならない複雑性の多くは気まぐれによるものだ。
インターフェイスを人間の社会制度やシステムに適合させるべく、いわば是非もなくそれらによって強制されているからである。
(引用終了)

最近、業務システムとかERPに僕自身が少し興味をなくしているのは、システム化したい業務そのものが元々複雑過ぎて、それを整理しようと言うよりも、現実の業務をいかに忠実にシステム化するかに注力する案件の方が多いからだ。
元々の業務が、日本的な複雑な組織体制を元に作られていれば、複雑なのは当たり前であり、それを忠実にシステム化するなら、複雑怪奇なままだ。
日本では、ERPをBPRとして捉えるよりも、自分達の業務中心に考えすぎているために、システムも複雑怪奇になりやすいような気がしている。

【4-2】可変性は、ソフトウェア品質の移植性や保守性を連想する。

アジャイル開発が重視する品質特性~保守性と移植性: プログラマの思索

(引用開始)
ソフトウェア実体は、つねに変更という圧力にさらされている。
(引用終了)

XPの言う「変化を抱擁せよ」と同じ。
ソフトウェアにとって、VerUpは宿命であり、常に変化が内在している。
ソフトウェアは変化しない固体として存在し得ない。

(引用開始)
純粋な思考の産物であってきわめて融通性に富んでいるので、ソフトウェアがより簡単に変更できるということもある。
ビルも現実には変更されるものだが、だれもが了解しているように、変更コストの高さが思いつきで変更しようとする者の気をくじく働きをしている。
(引用終了)

ソフトウェアに、仕様変更という名の保守はつきものだ。
それは簡単にできるように思えるから、簡単にソフトウェアに手を入れて、潜在バクを埋め込んでしまう。
ソフトウェア品質特性のうちの保守性を連想させる。

(引用開始)
大当たりしたソフトウェアはまずたいてい、すべて変更される。
あるソフトウェア製品が役立つと分かると、人々はもともと処理対象としていた領域ぎりぎりもしくはその領域を越えるような新しい使い方を試してみようとする。
主として、拡張機能のために変更して欲しいという圧力は、基本機能が気に入っていて新しい使い方を考えだす利用者から出される。
(引用終了)

これは、たとえば、Redmineが当初のバグ管理の使い方から、タスク管理、そして、アジャイル開発やWF型開発、さらには、事務処理ワークフロー、ハードウェア資産管理システムへ使い道がどんどん広がっていった事例を連想させる。
本来想定しなかった使い方が一般的になってしまい、その使い方をさらに使いやすくしたり、機能改善することで、ソフトウェアの複雑性がどんどん膨張する。
あらゆるソフトウェアは機能追加という変化にさらされている。

(引用開始)
大当たりしたソフトウェアは最初に書かれた対象である機械機器の通常の寿命よりも長く使用され続ける。
要するに、ソフトウェア製品はアプリケーションや利用者、慣習および機械機器といった文化的マトリックスにすっかりはめこまれているのだ。
そしてそれらは絶えず変化し続けるものであり、その変化がソフトウェア製品に容赦なく変更を強制するのである。
(引用終了)

たとえば、OSやDBやミドルウェアのバージョンアップとか。
あるいは、サーバー本体のリプレースとか。
たとえば、WindowsXP廃棄対応、WindowsServerのリプレース、OracleのVerUp、RailsのVerUpとか、iOSやAndroidOSのVerUpとか、色々思い出す。
つまり、ソフトウェア品質特性の移植性を連想させる。

こういうミドルウェアやOSのVerUpに伴うプログラム変更作業は、とてもしんどいものだ、と開発者なら誰でも知っている。
こういうつまらない開発基盤のVerUp作業は、ソフトウェアの外にある外部環境の変化によって生じるものであり、避けることは出来ない。

【4-3】不可視性は、ソフトウェア設計の難しさを連想する。

(引用開始)
ソフトウェアの構造を制限したり単純化したりすることは進歩したにもかかわらず、その構造は本質的に視覚化できないままになっている。
そのため強力な概念上のツールを作る意欲を阻害している。
その欠落は1人の人間の頭の中のデザインプロセスを妨げるばかりでなく、複数の人間の間でのコミュニケーションもひどく妨害する。
(引用終了)

UMLやDOAは、ソフトウェア構造を視覚化する問題を解決しようと試みていた。
SySMLもその流れだろう。

複雑性をコントロールするための設計技法は、歴史上いくつか考えれてきた。

たとえば、Nティア設計。
つまり、レイヤ化。

another level of indirection
「もう一段の間接参照」を導入すると、コンピュータのほとんどの問題は解決できる。

NFuji's Café: 「Beautiful Code」を読む(中)

ポインタを制する者はプログラミングを制する: プログラマの思索

MVCモデル、通信プロトコルの7層モデルもそういう考え方だろう。

他に、渡部幸三さんの観点でのDOAでは、業務・機能・データの3層構造の業務システムにおいて、業務レイヤとデータモデルのレイヤに複雑性を押しこんで、機能レイヤは複雑性をできるだけ減らす設計が良い、と提唱していた。
すなわち、機能レイヤはまさにプログラミングレベルなので、その部分の複雑性はできるだけ減らして保守性を高めようとする考え方。
つまり、複雑性というエントロピーは一定で変わらないと仮定した場合、人が携わる業務レイヤと、データモデルのレイヤに複雑性を落としこんで、複雑性をコントロールしようとするわけだ。

だが、これらの手法で、ソフトウェア本来の複雑性が本質的に解決されたのか、と問うてみると、正直分からない。

【5】一方、ソフトウェアの偶有的な複雑さは個別撃破している。

「高水準言語」は、たとえば、VBよりもRuby。
たとえば、VBはListやHashなどの基本ライブラリのAPIが非常に不足していて使いにくい。
たとえば、Rubyなら、そういう低レベルなライブラリは非常にAPIが揃っていて、VBよりも1行で書ける。
つまり、複雑性を軽減している。

「タイムシェアリング」は、たとえば、コンパイラ言語よりもインタプリタ言語、継続的ビルド管理、構成管理を指すのかな。

(引用開始)
考えていた内容をすっかりというわけではないが些細な点でどうしても忘れてしまう。
(引用終了)

この部分は、まさにソース管理、構成管理を連想させる。
たとえば、CVS、Subversion、Gitに至るまでの構成管理ツールの歴史を振り返れば、ソフトウェア開発プロセスにおけるブランチ管理、マージなどの作業の複雑性は軽減されている。

「統一されたプログラミング環境」はたとえば、VisualStudioやEclipse、IntelliJとか。

つまり、ソフトウェアを開発する作業そのものが生じる複雑性は、今までの歴史で生み出された技術によって、多少は軽減されてきた。
しかし、だからと言って、ソフトウェアの本質的な複雑性を攻略できたわけではない。
あくまでも、以前よりも大きい複雑なソフトウェアをコントロールできるようになった、というだけだ。

| | コメント (0)

2016/12/17

WindowsのRubyのバージョン管理はuruを使う

WindowsのRubyのバージョン管理はuruを使うと良い、という記事を見つけたのでメモ。

【参考】
Windows7でRubyのバージョン管理!pikの代わりにuruを使う。 - 思い付くまでタイトル未定

pikの替わりにuru~windowsで複数バージョンのrubyを切り替える~ - Qiita

jonforums / uru / wiki / Downloads ? Bitbucket

複数のRuby環境構築はrvmかpik: プログラマの思索

もうpikは使えなくなった。
代わりにuruをインストールする。

uru_rt.exeを、C:\toolsに配置
環境変数PATHにC:\toolsを追加

cd C:\tools
uru_rt admin install

uru_rt admin add C:\Ruby-2.2\bin

uru_rt ls
220p0 : ruby 2.2.0p0 (2014-12-25 revision 49005) [x64-mswin64_100]

uruはRubyのバージョンだけでなく、Gemも切り替えてくれるので便利。

| | コメント (0)

2016/01/12

Rails製次世代型CRMのFat Free CRM

Rails製次世代型CRMと記載されていた「Fat Free CRM」のリンクをメモ。

【参考】
Rails製、次世代型CRM・Fat Free CRM MOONGIFT

fatfreecrm/fat_free_crm ・ GitHub

Rails Hub情報局: いま読みたいRuby on Rails3アプリ 10選

Fat Free CRM - Ruby On Rails-based open source CRM platform

日本Cloud Foundryグループ ブログ: Fat Free CRM を Cloud Foundry で動かす

どんな中小企業でも、個人事業主でも、営業していたら、見込客や既存顧客の状態を管理したくなってくる。
そこで、CRMに見込み客や既存顧客を登録しておき、営業で見つけた情報や引合の情報を登録して、後で精査したい。

フリーのCRMと言えば、SugarCRMやvTigerCRMが有名だろう。
でも、Railsアプリと言えば、RedmineやGitlabが有名だろうが、Rails製CRMがないか、探していた。
そんな時に見つけたのが、Fat Free CRM。

(引用開始)
今回紹介するオープンソース・ソフトウェアはFat Free CRM、次世代型のCRMを標榜するソフトウェアだ。

Fat Free CRMはRuby on Railsで作られたソフトウェアで、SQLite3やMySQLで利用できる。ごく手軽に導入できるのが利点だ。インタフェースは非常に見やすい。ラベルが色分けされているだけで随分見やすさが変わってくることが実感してもらえるはずだ。

主な機能はタスク、キャンペーン、顧客情報、案件のステータスなどを一元的に管理できる。顧客に対してタスクを紐づけることで、どの顧客が工数が多くなっているのか等も分かる。検索は各アクションに沿ってフィルタリングが可能で、細かく検索できるようになっている。
(中略)
一般的なCRMというと入力項目がとても多く、面倒な感じがしていたがFat Free CRMについてはすっきりとしたインタフェースも手伝ってそんな印象はない。また、スケジュール管理とかぶる機能が多いのも一般的なCRMでは多かったが、Fat Free CRMではタスクくらいだ。次世代型にふさわしい、進化したCRMと言えそうだ。
(引用終了)

パッケージ製品のCRMは、どうしてもUIが使いにくいし、見栄えも良くない。
一方、Rails製のCRMの方がUIも先進的だし、最新の技術も反映しやすいはず。
Fat Free CRMの画面キャプチャや概要を読むと、使いやすそうに見える。

DBに顧客情報や問合せ情報が登録されていれば、そのDBを直接参照することで、他システムとも連携しやすくなるはず。
個人的には、CRMにおけるサポートデスクの問合せ管理はRedmineの方が使いやすいと思うので、Fat Free CRMとRedmineが相互連携できるといいなあと思ったりする。
色々調査してみたい。

| | コメント (0)

2015/07/18

ツールでプロセスを実装すべきか、プロセスを確立してからツールを導入すべきか

Redmineを導入したいという話を受けて、Redmineを導入した時、後で気づくのは、ツールでプロセスを実装すべきか、プロセスを確立してからツールを導入すべきか、という問題。
ラフなメモ書き。
結論はなし。

【参考】
akipiiさんはTwitterを使っています: "改めて読むとなるほどを思う。「ツールは高速道路だが、その上を時速何キロで走れるのかはチームの成熟度に依存しているのだ。」書評 アジャイルソフトウェアエンジニアリング http://t.co/mwzki9EZGi @ryuzeeさんから"

OjaさんはTwitterを使っています: "管理者受けし易い代わりに、うまく使えるかどうかも管理者次第なので、管理者の実力と評価がそのままRedmineの評価になるんじゃないかという仮説 RT @t_yoshi_tomi 何故、 Redmineを気に入る人と Redmineを毛嫌いする人がいるのだろうか・・・"

よしむさんはTwitterを使っています: "@kawanishi_ameya プロジェクトによって運用具合もバラつきがありますし、管理者次第というところが影響してくるんですね・・・(泣)"

akipiiさんはTwitterを使っています: "同感。RT @n_enot: チームでのソフトウェア開発って本当に難しくて、だからみんなPullRequest駆動やチケット駆動、あるいはもっと単純に相談&告知、最悪な例だと申請&ハンコ承認といった、とにかく協調して作業する方法が探られているわけです。"

みずのり(みずののりゆき)さんはTwitterを使っています: "個人的に。 プロセスとツールの両方を同時に変えるのは難しいので、まずはEXCELな従来ツールで展開ツール活用時に近いプロセスを実装。 そこから”ツールの方が便利ですよ”とやってみると導入しやすい感。 前者のプロセス変更に対応出来ないチームにはツール導入しても使われないっす。"

みずのり(みずののりゆき)さんはTwitterを使っています: "最近やったのはプロセス導入の段階で、かなり苦労して試行錯誤して枠組み作ったけど、そのプロセスの安定した形態はすぐにツールに置き換え可能なものでしたとさ。 チケット駆動の考え方をプロセスにしたので、redmine置き換えがすぐに出来るのは当たり前なのですが^^;"

僕個人の経験では、Redmineというツールを導入した後に、こういうふうにプロセスを回すのだな、と気づきながら運用していた。
だから、ツールを使いながら、あるべきプロセスを導き出したように思う。

でも、実際はそうではなかったかもしれない。
ツールの導入前は、アジャイル開発を実践した経験はほとんど無かったけれど、アジャイル開発の知識は持っていたし、こういうふうに運用したい、という思いはあった。

WF型開発できちんと変更管理するやり方も、色んなSIを渡り歩きながら、学んでいた。
SIer特製の障害管理Webシステムへの障害票の書き方、コミットする時には障害管理番号を記載すること、CVSのコミットログに変更理由を記入すること、などの運用ルールはある程度分かっていた。
だから、Redmineを障害管理からタスク管理へ発展させて使う方法はマッチできた。

実際は、プロセスが確立されたイメージを持ってツールを導入していたのだろう。

ツールは高速道路であり、上手く使えば、ゴールまで速く到達することはできる。
でも、高速道路の走り方も多少はあるし、車のエンジン(=チームの能力)が性能を出し切れなければ、国道を走っている時と変わらないかもしれない。

色々考えてみる。

【追記】
下記の記事が参考になる。

NotesのDB設計ができる人はチケット管理システムのプロジェクトへの適用にアドバンテージを持っている - 室長のひとりごち

(引用開始)
ところで、Notesってあったでしょう。あ、今もあるか。アレのDBの設計を経験したことがある人は、チケット管理システムのビューやフォームの設計のハードル皆無だと思います。

ラベルをもったデータ項目を追加するか、標準のデータ項目を使いまわすことで、システム開発手法で管理したい情報を持たればいいとか、開発プロセスごとで見たい情報をビューで見せることができるとか、そういったことがわりとすんなりイメージできます。
(中略)

そのときのワタシの頭の中にあったことは「問題解決をするためにツールの導入を考えていたのか」と聞かれれば答えは「ノー」です。問題はプロセスにあると見切り、その問題のあるプロセスままだと潜在化したままで進行してしまうので「可視化」が問題解決の決め手と思った、と当時判断したと思います。今でもそうすると思いますが。

そこには、そう判断した根っこにはチケット管理システムはプロセス管理システムとして使える、と思ったんですね。そのおおもとを辿るとNotesもその1つの要素なのかもしれません。

その点から言えば、確立した開発プロセスのイメージを持っているから、適用するプロジェクトの課題解決のための1つの手段としてツールを導入することを判断した、のではないかと思うのです。
(引用終了)

| | コメント (0)

2015/05/10

IntelliJでRailsソースをリモートデバッグ

IntelliJでRailsソースをリモートデバッグする記事を見つけたのでメモ。

IntelliJ IDEA 13.1 + Ruby plugin 6.5.0.20140314 DE リモートインタプリタ Rails開発 - Qiita

EclipseやVisualStudioでも、JavaやC#の環境でデバッグ時に、ローカルサーバー上のWebサービスのソースをデバッグできる設定がある。
RubyのIDEでは、IntelliJ+RubyプラグインまたはRubymineが優れていると聞いているが、同様にできるみたい。
Rubyのようなインタープリタ言語でリモートデバッグできるとはすごいな、と思ったりする。


| | コメント (0)

2014/01/04

ITの地殻変動はどこで起きているのか~アーキテクチャ設計技術にクラウドが必須になった時代

2014年になって、ITの地殻変動がどこに起こっているのか、を考えてみる。
#ラフなメモ書き。

【1】最近感じることは、Webアプリをプログラミングするアプリケーションエンジニアよりも、サーバー基盤を構築するインフラエンジニアの方が目立つというか輝いて見える時が多い。
何故なのだろう?

また、先月の日経BP主催のITアーキテクト カンファレンスでは、エンタープライズシステムの構築に携わるITアーキテクトを対象にしているが、その内容はすべて、クラウドがキーワードだった。
DOAやOOAは全く含まれていない点が衝撃だった。

ITアーキテクト カンファレンス 2013

最近の流れを見ると、アーキテクチャ設計の技術では、DOAやOOAは既に古い技術であり、クラウドが席巻しているように見える。

【2】最近のバズワードである「クラウド」には、否定的な意見を持つ人も多い。
ITの歴史の延長線上にあるだけで、そんなにすごい価値があるわけではないだろう、と。
単に仮想化なんでしょ、と。

クラウドサービスも、大昔のデータ計算センターや電算受託から始まったシステムサービス提供形態の現時点での変化形に過ぎない、と。

実際、ERPやメールサーバなどをクラウドへ構築する場合でも、フィットギャップ分析、セキュリティレベル、運営のコンセプト確認、負うべきリスクの整理、サービスレベル(SLA)の定義、など、従来の手法で検討する必要がある点は変わらない。
システム、ネットワークなどの利用面の進展があっても、利用に当たっての検討項目は本質的には同じである。

【3】しかし、クラウドが新しい観点をもたらし、アーキテクチャ設計に大きな影響を与えた点は2つあると思う。

【3-1】一つは、インフラ構築もアジャイルにプログラミングで開発できること。
その意味については、下記の記事で色々考察した。

クラウドの本質はインフラ管理のIT化: プログラマの思索

サーバー構築を構成管理とTDDで作業する時代になってきた: プログラマの思索

JenkinsによるLinuxサーバの設定変更管理yggdrasilの運用事例: プログラマの思索

「Infrastructure as Code」というキーワードがまさにそうであるように、サーバー構築手順は全てプログラム化できる。
従来は、サーバー購入や構築手順をあらかじめ計画段階で入念に実施し、レビューしてから作るというウォーターフォール型開発っぽいやり方しかなかったけれど、クラウドのおかげでサーバー構築もアジャイルに開発できる。

アジャイルに開発できる利点の一つは、失敗を何度も許容できる点があるだろう。
特に、サーバーの障害テストや負荷テストを何度もやり直せる利点はとても大きい。
従来なら、サーバーの負荷テストや障害テストは、準備も実行もすごく手間がかかりすぎて、何度もやり直すべき作業ではなかった。
アジャイルに障害テストや負荷テストを実施できることで、最初の計画を完璧にしなくても、プロトタイプのようにサーバーを構築して実現可能性(フィージビリティ)を調査したり、運用に合わせてハードウェア構成を柔軟に変える、などのオプションを持つことができる。

障害を故意に起こさせるツールで耐障害性を高める: プログラマの思索

また、クラウド化することで新たに判明する点は、ソフトウェアの品質がそのままコストに跳ね返ってくる点だろう。
例えば、CPU使用量やメモリ使用量を10%削減できれば、請求代金を10%削減できるのだ。

クラウドではソフトウェアの品質が課金の差として出てくる: プログラマの思索

つまり、クラウドでは下記の公式が成り立つ。

ソフトウェアの品質の差=パフォーマンスの差=課金の差=コストの差=利益率の差

従来は、一度、サーバーを構築したら、そのハードウェア構成を変えるのは、次のハードウェアリプレースまでできなかったが、クラウドなら、柔軟にハードウェア構成を変えることができる。
したがって、クラウドによって、ソフトウェアの品質特性として、特に効率性(パフォーマンス)がより重要になってきた側面があるだろう。

他にも、クラウドによって、システムの移植性が高まる、信頼性の観点は壊れないシステムよりもすぐに直せるシステムの方が重要、など、品質特性の観点が変わってきた。
今後は、クラウドとエンタープライズのシステムの組合せでは、機能性や信頼性よりも、保守性・移植性・効率性の品質の方が重視されてくるだろう。

アジャイル開発が問題点をすり替えた品質特性~機能性と信頼性: プログラマの思索

アジャイル開発が重視する品質特性~保守性と移植性: プログラマの思索

なお、クラウドで使われるツールで注意すべき点は、Chefなど、Rubyで書かれたプログラムが多いこと。
クラウド時代のサーバー構築では、Rubyという技術が必須になってきているように思える。

【3-2】もう一つは、DOAやOOAやサーバー構築の設計では、その時代の技術の制約があったために、バッドノウハウになっていた箇所に対し、クラウドを使うことで本来の目的がクローズアップされたこと。

クラウドを使ったサーバー構築の設計では、クラウドデザインパターンがまとめられているので、参考にすべきだろうと思う。

クラウドデザインパターン~インフラ方式設計のベストプラクティス集: プログラマの思索

クラウドアーキテクティング原則 - AWS-CloudDesignPatternに掲げられた下記の原則は、クラウドの使い方について的確に示していると思う。

◆できるだけサービスを利用
◆机上実験よりも実証実験
◆スモールスタートからスケールアウト
◆変化に対し全レイヤで対処
◆故障のための設計(Design For Failure)
◆最初だけでなく周期的なカイゼン

また、DOAでは、サマリ系テーブルは夜間の日次バッチ処理(特にCobol)で作る、とか、正規化しているために参照関係の複雑なテーブルを結合して参照するしかない、などの弱点が従来はあった。
でも、クラウドが出てきて変わった点は、MapReduceのような並列処理と相性が良いので、大量データを短時間で処理できる設計も可能になったこと。

更には、RDBを使うとパフォーマンスが出ない場面では、クラウドと相性の良いNoSQLを組み合わせて、KVSやドキュメント指向DB、列指向DBなどを使うことで、問題解決できる場面があること。
よく聞く場面は、SNSやソーシャルゲームのログイン時にユーザ情報を参照する処理のように、単純な参照処理だが大量のアクセスが発生する状況で使われる。

データベース技術の今後の動向: プログラマの思索

最近「ビッグデータ」というバズワードが頻出される理由は、クラウドが並列処理と相性が良く、大量データを短時間に処理できるために、大量データから意味ある論理を導くデータマイニングが注目されているからだろうと思う。
従来のDOAでは、データウェアハウスのような設計思想もあったけれど、パフォーマンスが悪くて、なかなか手軽に使えなかった状況があったからだ。

現場の業務システムは、運用後にかなりのトランザクションをためているものの、それらのデータを解析(データマイニング)して、そこから得られた知恵を再利用する手法はほとんど取られていない。
よくある例は、購買履歴から顧客の購買動向を分析するCRMが欲しいという要望が多かったが、その仕組みが従来はなかなか作りにくかった、という弱点があったと思う。
Amazonのおすすめ商品のような協調フィルタリングを実装するのは敷居が高い。

他にも、従来のDOAでは、製造業向け生産管理システムのMRP(部品の所要量計算)、会計システムの自動仕訳とPL・BSレポート出力も、普通は日次バッチ処理で1日1回(または月次バッチで月末1回、年次バッチで1年に1回)作られるだけだった。
従来のDOAを支えるRDBMSの制約、バッチ処理プログラムの性能が出ないなどの制約などの理由で、夜間バッチ処理でしか対応できなかったのだ。

「オンプレミス・システムの終わり」の始まり~AWSでのミッションクリティカルシステムの稼働 - 急がば回れ、選ぶなら近道

基幹系バッチ処理をHadoopで高速化: プログラマの思索

Hadoopの本質は分散I/Oにあり~クラウド時代の非同期処理: プログラマの思索

クラウドのもう一つの本質~ソフトウェアの可搬性を確保する: プログラマの思索

でも、クラウドとデータマイニング・データ集計の並列処理を組合せることで、CRMのデータを手軽に作り出せる。
MRPによる原価計算や、自動仕訳後のPL・BS出力も1日数回以上実施できるようになる。
そうすれば、原価計算や会計処理、CRMなどの経営分析も、アジャイル開発っぽく、何度も試行錯誤しながら仮説検証していくスタイルを実施しやすくなる利点がある。

最近、リーンスタートアップという経営手法が注目されている。
その理由は、経営手法でもアジャイル開発のやり方を実践して効果が出せるからだと思うが、その背景には、クラウドを使って、少人数でWebサービスをリリースすればすぐにビジネスを開始でき、スケールアップも容易である特徴を生かしているからだと思う。

クラウドという単なる一つの技術が、従来のDOAやOOAでは解決しにくかった問題に対して有効である場面が増えてきている。
それら効果についても今後、追いかけてみる。

【追記】
クラウドとセットで語られるNoSQLについては、7つのデータベース 7つの世界の本が個人的にはお勧め。
7種類のDB(PostgreSQL、Riak、HBase、MongoDB、CouchDB、Neo4J、Redis)の特徴について、広く深く記載している。サンプルソースもあるので、とっつきやすい。

| | コメント (0)

より以前の記事一覧