性的種付け行為?
以下、動的型付け言語厨が エディタで十分!説を披露してくれます
いや、言語が酷いからEclipseが凄い環境になったんだろ? エディタで充分とまでは言わんよ、Eclipseは実際に凄い環境なのだから
言語が酷くないとEclipseが対応してくれず エディタも不十分 詰んでるなw
言語が酷いとIDEサポートも出来ない。 色つけるだけしかできないのなら、viやemacsで十分。 酷い言語は可哀想である。
Eclipseが対応してない言語なんてあるの?
動的型付け言語にリファクタリングなんていらないだろ 書いて捨てるだけ
参照透明なら順序すら気にせず大胆にリファクタリングできるよ! これからは純粋関数型言語でリファクタリングの時代ってことだね! んなわきゃーない
C++はかなりやりにくそうだな 名前の変更も苦しそうjだし
>>10 まあ、大変だろうね。開発者の苦労は知らないがこんなことが出来るらしい。
http://www.wholetomato.com/products/featureRefactoring.asp Rename
Extract Method
Encapsulate Field
Change Signature
Move Implementation to Source File
Add Member
Add Similar Member
Document Method
Create Declaration
Create Implementation
Create from Usage
Implement Interface / Virtual Methods
このスレッドは天才チンパンジー「アイちゃん」が 言語訓練のために立てたものです。 アイと研究員とのやり取りに利用するスレッドなので、 関係者以外は書きこまないで下さい。 京都大学霊長類研究所
アイちゃん遅いよw
14 :
uy :2012/06/11(月) 16:04:52.35
操作しやすいな
15 :
uy :2012/06/11(月) 16:12:57.08
リファクタリングという単語は、勘違いしたゴミッカスOO厨に侵食されたので これからはソースコードの最適化という単語を使っていく 勘違いなきよう 静的言語がそんなに大好きなら、勝手にやってろと思う ただし、俺を巻き込むな 一人でやってろ
17 :
uy :2012/06/12(火) 03:18:54.22
ゴミみたいなスレだな
アプリのバージョンアップというのは 家の増改築に当たると思う。 最初の想定外の増改築を行う時 既存の部分の補強が必ず必要。 そうしないと言え全体が壊れる。 この補強作業こそがリファクタリング。 リファクタリングはいわば将来への投資 最適化とは目的が違うな。
>>18 リファクタリングの必要性を説くべき相手は経営層
「会社の規模が大きくなったら組織化・体制づくりが必須」
みたいなたとえが合ってるんじゃないかな
最適化どころか形式ばったムダばかり生まれる
それでもたがいに足を引っ張り合う秩序崩壊よりはずっとマシ、と
21 :
uy :2012/06/13(水) 13:39:56.55
頭も悪い奴がどんどん言葉の質を下げていく 勝手にやってろゴミ
22 :
uy :2012/06/13(水) 16:53:41.38
静的言語はゴミでしかない
uyは就職しろ まじでゴミカスになるぞ
24 :
uy :2012/06/15(金) 13:21:12.20
ゴミ
ゴミカス
イザナミだ
uyは就職しろ まじでゴミカスになるぞ
28 :
uy :2012/06/16(土) 18:04:51.85
人は生きているだけで、他の生物を殺す 綺麗な魚を、綺麗な鳥を、牛など、野菜を食べ、 そしてゴミを排出する それが人だ、 だとすれば人はこんなことをやっている場合じゃない 綺麗なものを壊し続けているんだから 多くの命を奪い続けているんだから せいぜい何かマシで綺麗なものを創作しろ
最初にRefactoringBrowserが実装されたのは動的言語であるSmalltalk。
>>11 のリストの機能も代替サポートされとるよ。
メソッド名を変更するとき、関係ないクラスのメソッドまで 全部リネームする(そうしないと壊れる)のを「代替機能がある」 と呼ぶなら、そうだね。
最初にRefactoringBrowserが実装されたのは動的言語であるSmalltalkだが、 静的型付け言語のほうが、RefactoringBrowserをもっと効率良く 安全に行えることが判明した。
1000 :uy ◆xVOGOO9ev6 :2012/06/23(土) 12:35:29.68 俺は動的言語の問題点をいくつあげてもwwwww 静的言語よりはマシだと確信してるわwwwwwwwwwwwwwwwww 静的言語の問題点をなぜ挙げないかって?? 見放してるから、問題点を指摘さえしないってことだよwwwwwwwwwww 気づけバカwwwwwwwwwwwwwww
33 :
デフォルトの名無しさん :2012/07/24(火) 23:55:34.03
javascriptゴリゴリ書かせられてるんだが 明らかにクソだとわかってても直す気がなくなっていく これが動的言語・・・・
動的、静的より周辺ツールを作りやすい言語を作るべき てか、ただのエディタでコード習性とか死ぬ
35 :
デフォルトの名無しさん :2012/08/02(木) 21:53:42.31
動的言語はまともなツールが作れない
スクリプトを書き捨てるだけの言語に リファクタリングとかある訳ないだろ
動的型付言語でリファクタリングで困る事ってなんだ? 関数名書き換えたいってなら、同じシグニチャの関数列挙して ユーザーがOKを押せば随時置換してくれる用なもんで十分だけど 他に何か困ることがあるか?
名前変更・・・動的型付でも可能 移動・・・動的型付でも可能(リファクタリング以前に統合開発環境なら大体できる) ローカル変数の抽出・・・動的型付でも可能 定数の抽出・・・動的型付でも可能 ローカル変数をフィールドに変換・・・動的型付ならthisなり@なりつければ済むので不要 匿名クラスをネストに変換・・・Java以外の言語なら不要 メンバー・タイプをトップ・レベルに変換・・・動的型付でも可能 インターフェースの抽出・・・動的型付の場合大体は不要、ただしObjective-Cの様に存在する場合でも問題なく可能。 スーパークラスの抽出・・・可能であるが、多用すべきじゃない。 メソッドの抽出・・・動的型付でも可能 インライン化・・・動的型付でも可能 メソッド・シグニチャーの変更・・・同一シグニチャの関数を列挙し確認した上で変更することで可能 静的片付けでも変更可能不可を判断しなきゃ行けないんで手間は変わらない むしろインターフェースの分離が必要なので静的型付の方がメンドイ 総称型引数の推測・・・不要 Eclipseの機能だとこんなもんか。てかEclipseのリファクタリング機能って 殆ど単なるマクロ系機能でリファクタリングじゃないよな
39 :
デフォルトの名無しさん :2012/08/04(土) 21:46:16.95
>>382 お前、「リファクタリング」を知らないだろ。
そこに出ている名前は、リファクタリングの著名な本で
リファクタリングとして定義されている機能なんだが。
40 :
デフォルトの名無しさん :2012/08/04(土) 21:49:04.32
>>37 その方法で、countっていう名前を
置換したら、バグだらけになったよw
41 :
デフォルトの名無しさん :2012/08/04(土) 21:58:23.69
なんで、
>>1 にしっかりと
リファクタリングが「しやすい」って書いてあるのに
出来る出来ないの話に持って行こうとするんだろうね。
動的言語の場合は面倒だったり、人間の判断が多く必要だったり
修正完了までに時間がかかったり、バグを起こしやすいってだけで、
出来るか出来ないかで言えば、出来るに決まってるだろ。
それは、反論になっていない。
しにくいという事実を否定してないんだから。
>>40 countのどこにシグニチャが出てくるのか詳しく
>>41 具体的にどうしにくいの?。
>>38 に出てる内容だと、動的静的関係あるのってメソッド名だけだよね。
それ以外リファクタリングツールがあれば何も変わらないよね。
>>40 タダの置換じゃなくリファクタリングツールつかえよ
45 :
デフォルトの名無しさん :2012/08/04(土) 22:04:41.36
>>42 Rubyしらないの?
countという名前のメソッド作れるんだが。
不要な()を書く必要はない。
46 :
デフォルトの名無しさん :2012/08/04(土) 22:09:15.63
>>43 動的言語だと、実行時にしかわからない情報が多いから
静的なリファクタリングと相性が悪い。
一見修正できたように見えても、実行するとエラーが起きる。
リファクタリングってのは、動作を変えずにコードを変えることだが
静的言語だと、「動作を変えない」という保証を
リファクタリングツールが行えるのに対して、
動的言語だと、人間が保証しなければならない=時間がかかる。
静的言語・・・リファクタリング開始 → 終了(完璧に動く)
動的言語・・・リファクタリング開始 → テストコードを動かす → 完璧ではなかった → 人間が問題箇所を調べる → 修正する → 完璧になるまで繰り返し → 完璧って保障は誰がするの?
>>45 ()があるか無いか関係なくね。a.xxxとあれば列挙して名前を書き換えていいか確認したら
置換にOK指示をだせばいいだけじゃん
>>46 コンパイルエラーが発生する代わりに実行時にエラーがでるのはリファクタリングに限った話じゃない
結局テスト云々の問題になる。そもそも静的型付だって安易に関数名を変えられない。
簡単に書き換えられるのは仮想じゃない関数だけだ。関数名変えるなら継承元や
派生全てへの影響を考えて調整する必要がある。動的型と同じ最悪実行時エラーも招く。
(今までオーバーライドしてなかった関数をオーバーライドしてしまった等)
48 :
デフォルトの名無しさん :2012/08/04(土) 22:19:39.91
> 置換にOK指示をだせばいいだけじゃん ほらそれそれ、 人間がやる作業がある。 置換してOKか?すぐに分からない。 時間がかかる。
49 :
デフォルトの名無しさん :2012/08/04(土) 22:22:19.24
>>47 動的言語だと、それが仮想関数かさえわからないよな?
関数名書き換えられないと自分で認めてるのに気づいた?
静的言語だと、ちゃんと仮想関数まで追尾してくれる。
継承元や派生すべての影響を考えて修正してくれるんだよ。
もちろん、今までオーバーライドしていなかった。ということも検知してくれるし、
新たにオーバーライドしてしまうようなリファクタリングをしようとしたら
ちゃんと教えてくれる。
>>48 静的型でも同じじゃん
>>49 >関数名書き換えられないと自分で認めてるのに気づいた?
できるけど、静的型でも動的型でも同じ問題にぶつかるって書いてるよ。
>静的言語だと、ちゃんと仮想関数まで追尾してくれる。
>継承元や派生すべての影響を考えて修正してくれるんだよ。
置き換えて大丈夫かどうか調べにゃならんのは同じでしょ
>>49 一応言うけど、動的型言語の場合シグニチャが同じなら
全て同じインターフェースの関数を利用してると同義なんだよ。
静的型付でもインターフェースの影響範囲を全部しらべるよね。
動的型は、実体が同一のJavaやC++の様なメンバー関数形式じゃなくて メッセージとメソッド形式だからなぁ。切り口を変えれば手間も対して変わらんってのは メンバー関数な人には理解しづらいんだろ
>>49 >もちろん、今までオーバーライドしていなかった。ということも検知してくれるし、
>新たにオーバーライドしてしまうようなリファクタリングをしようとしたら
>ちゃんと教えてくれる。
動的型付なら同じメソッドもってりゃ全て派生みたいなもんだし
もし警告が出るようなツールがあっても全てのクラスに警告がでるから
そもそも意味がないでしょ
54 :
デフォルトの名無しさん :2012/08/04(土) 22:50:31.77
>>50 > 置き換えて大丈夫かどうか調べにゃならんのは同じでしょ
なんで、意味的に一致する所を全部書き換えるのに
いちいち調べなきゃならんのだ。
55 :
デフォルトの名無しさん :2012/08/04(土) 22:51:14.92
>>53 だから、そのさが静的言語のリファクタリングのしやすさに繋がってるの。
>>54 addを2つのクラスなりプロトコルなりインターフェースなりから受け継いでて
片方をappendに変える事になったらもう片方にも影響するだろ
この時わざわざ名前を変えたのは"本来意味が違う"のに間違った名前をつけてたからだ
意味と名前がそぐわないから名前を変えるってのはリファクタリング理由の一つだろ?
>>55 「だから」になってないよ。同じメソッドを持ってるクラスが全て同じインターフェースを実装してる場合と
何が違うのか一切反論になってないし
58 :
デフォルトの名無しさん :2012/08/04(土) 23:02:25.02
>>56 その片方に影響するという事実が
静的言語なら検出可能になる。
実際にリファクタリングをしようとしたら
動的言語だと、人間が判断してやるしか無く、
ミスするのが目に見えているが、
静的言語だと、「このメソッドは他のクラスからも継承しているため
変更するのは危険です」と警告が出せるだろう。
59 :
デフォルトの名無しさん :2012/08/04(土) 23:04:07.30
>>57 > 同じメソッドを持ってるクラスが全て同じインターフェースを実装してる場合
動的言語だと、本当に同じインターフェースを実装しているかが検出不可能。
メソッドを実行時に付け加えたり外したりするから、
どうやっても確実な情報が得られない。
>>58 他でも出てるが動的型付なら全て同じインターフェースやプロトコルなんかを実装してるのと同じ。
警告出すんなら全部の同じメソッドを持ったメソッドに出さなきゃならんだけで警告自体意味がない。
>>59 それはjavascriptとかプロトタイプベースの問題で
動的型付言語と別問題だろ
>>59 静的型付言語に出来ない機能を引き合いに出してどうすんだよ。
>>59 golangとかC++のsignature(gcc拡張)とかで静的型言語でも
実装できそうな機能じゃあるが、静的だと簡単になるか?
つつく所がメソッドのリネームしか無いのか・・・
65 :
デフォルトの名無しさん :2012/08/05(日) 00:24:52.03
>>62 動的言語は静的言語で出来ないことを出来るようにしたために
実行前に判断できていたことをできなくしてしまった。
実行時にメソッドを変更するとか、ほとんど必要とされない機能。
なぜなら、ほとんどのことは実行前に静的に変更すること、
つまり何らかのメタ情報を元にコードを自動生成する機能で対応可能だから。
>>64 シグネチャの変更やクラス構造の変更までくると
動的言語は太刀打ち出来ないからね。
この話をすると、静的言語の圧勝になる。
66 :
デフォルトの名無しさん :2012/08/05(日) 00:26:37.83
たとえば、Railsとかで有名な 「データベース定義を元に実行時にメソッドを生成する機能」なんかは データベース定義を元にクラスを生成するコードジェネレータを使えば、 実行前にメソッドを生成することが可能。
>>65 プロトタイプの問題で動的型付け関係ないよね
>>65 静的型付け言語でメソッド差し替えできた場合は楽にリファクタリングできるの?
69 :
デフォルトの名無しさん :2012/08/05(日) 00:46:39.58
>>68 メソッド差し替えは目的ではない。
なぜそんなことをするのかから
話を聞こうか。
>>69 差し替えのメリットは無効化かな、静的型付言語の場合はデリゲート用。
静的型付言語でのメソッド追加のメリットは型を合わせられる点。
var a Prototype
var b Concept
b = a // Conceptに必要なメンバーが足りないのでコンパイルエラー
a.Example := func( _ Prototype )(){}
b = a // Conceptに必要なメンバーが足りているのでコンパイルが通る。
71 :
デフォルトの名無しさん :2012/08/05(日) 00:59:09.80
> 差し替えのメリットは無効化かな 意味不明
72 :
デフォルトの名無しさん :2012/08/05(日) 01:00:12.59
> b = a // Conceptに必要なメンバーが足りないのでコンパイルエラー > a.Example := func( _ Prototype )(){} > b = a // Conceptに必要なメンバーが足りているのでコンパイルが通る。 こんなもん、実行前にやればいいだけの話だな。
73 :
デフォルトの名無しさん :2012/08/05(日) 01:02:39.96
実行時に、メソッドを付け加えたり 外したりするのは間違いなんだよ。 どうせ実行時に付け加えたメソッドを 使っているコードをあらかじめ書いてるんだ? つまり、実行前にわかっていることなんだよ。 コード見れば実行前にわかっていることを 実行時に行うのはおかしい。
>>71 空の動作を与えれば実行したくない動作をしなくなる
応用すれば、使い捨てのスタブオブジェクトを作れる
>>72 静的言語の話だから当然実行前だよ
もしかしてクラス内で宣言しないと静的型付言語じゃないと思ってる奴がいる?
76 :
デフォルトの名無しさん :2012/08/05(日) 01:13:40.55
>>74 実行前に
> b = a // Conceptに必要なメンバーが足りないのでコンパイルエラー
> a.Example := func( _ Prototype )(){}
> b = a // Conceptに必要なメンバーが足りているのでコンパイルが通る。
こんな、実行文のような書き方で
クラス定義をする言語を知らないのだが?
擬似言語ならこんな感じがいいでしょう。
class Concept { ... }
partial class Concept {
func partial Example() {}
}
C#っぽく書いたが、静的言語でクラス定義をコンパイル時に拡張する方法の提案。
動的言語はアセンブラと同じようなもので、実行時に自分自身を書き換えることで
いろんなことができるけど、それは応急処置みたいなもので、その先に進化の道はない。
本当に実行時にやらなくてはいけないことなんて、すごく少なくて、
それを無くすことで、リファクタリングはより一層便利なものになる。
>>73 ぶっちゃけメソッドのつけ外しがメリットが大きなメリットだとは思ってない
静的型言語でも可能だから動的型固有の問題じゃないといいたかっただけ
>>76 golangの様な言語じゃないと無理だよ。
C#方式じゃインターフェースとクラスの結合が必須だから実現できない。
80 :
デフォルトの名無しさん :2012/08/05(日) 01:25:52.06
>>79 大有りだってw
実行前に決まっていることというのは、
コンピュータがすべてを把握できる。
実行しないとわからないこと、つまり未来はコンピュータにはわからない。
リファクタリングは実行前に行う作業だ。
リファクタリング以前に情報がわかるのとわからないのとでは
できることに大きな差がある。
81 :
デフォルトの名無しさん :2012/08/05(日) 01:27:11.06
>>77 > 静的型言語でも可能だから動的型固有の問題じゃないといいたかっただけ
そりゃメソッドの追加とか可能だろう。
だけど、それが実行前に行われるってところが重要。
それがリファクタリングのしさすさに影響してくくる。
そういやgolang系統じゃなくてもJavaとかなら近いことができるか Concept b = new Concept() { Prototype prototype = new Prototype(); int function() { prototype.function(); } void example(){色々} }
>>80-81 静的型と動的型で同じコードリファクタリングして具体的にどう変わる?
84 :
デフォルトの名無しさん :2012/08/05(日) 01:31:24.69
>>83 質問が意味不明。
アメリカに行くのに、船で行くのか、飛行機で行くのかと
聞いているようなものだ。
具体的に変わるもの? 手間と時間だろ。
>>84 例えば
>>82 と動的型言語で等価なコードを書いてた場合どう変わる?
メソッドを追加するという行為に対して結局どっちもリファクタリングの手間は変わらないじゃん。
86 :
デフォルトの名無しさん :2012/08/05(日) 01:38:35.24
メソッドを追加するのは、動きが変わっているから リファクタリングではない。単なる機能追加だ。
もっと具体的に書こうか。名前変更の際、静的型付言語ならConceptというインターフェースのexampleメソッド全てを書き換える。 動的型言語ならexampleというインターフェースのexampleというメソッド全てを書き換える。 結局手間は変わらない。
89 :
デフォルトの名無しさん :2012/08/05(日) 01:43:09.54
リファクタリングではないが、メソッドの追加に 伴う問題に、静的型付け言語のメリットは存在するぞ。 あるクラスAにfooというメソッドを追加するとき Aを継承したクラスBですでにfooというメソッドを定義していた。 こういう場合は予期せぬバグになるだろうから 実行前に検出するのがベターだ。 つまりJavaのoverrideアノテーション機能の話だよ。
>>86 メソッド追加をリファクタリングか議論してるんじゃなくて
メソッド追加があるものをリファクタリングするのは難しいって話してるんだよ〜
わかるぅぼくぅ?
91 :
デフォルトの名無しさん :2012/08/05(日) 01:45:55.96
>>87 意図的に手間がかかる部分を省略しないように。
Conceptというインターフェースのexampleメソッド全てを書き換える。
書き換えた場合に、Conceptというインターフェースそのものではなく、
そのexampleメソッドを使っているコードすべてを書き換えないといけない。
ここ、ここが一番手間がかかる部分で
お前が意図的に省略したところだよ。
これ、全て自動でやってくれるんですよ。
静的型付け言語のリファクタリング機能なら。
93 :
デフォルトの名無しさん :2012/08/05(日) 01:47:18.27
94 :
デフォルトの名無しさん :2012/08/05(日) 01:48:58.08
>>91 なるほど、たしかにそれはそのとおりだ。
exampleすべてを置換するわけにもいかない。
exampleが該当クラスのexampleであるかは
obj.exampleのobjが該当クラスかどうかの情報が必要になる。
つまり変数の型情報が必要になる。
>>91 動的片付けなら同一シグニチャのexample全てを書き換える
明示的にインターフェースを分離したいなら最初から
conceptExampleの用にインターフェース名が名前に含まれる訳で結局変わらんよ
96 :
デフォルトの名無しさん :2012/08/05(日) 01:51:22.56
> 動的片付けなら同一シグニチャのexample全てを書き換える 同一シグニチャでも、全く関係ないメソッドはどうする?
Objective-Cの糞長いメッセージ名なんかがいい例じゃん メッセージ名が同じなら同じインターフェース。メッセージ名が違うなら違うインターフェース。
98 :
デフォルトの名無しさん :2012/08/05(日) 01:54:12.44
型がない言語だと、シグニチャ=引数の数になっちゃうから 関係ないのに同一シグニチャになる可能性が多いんだよな。
>>96 動的型付言語の流儀として最初から作っちゃいかんだろ
もし有ったらそれこそリファクタリングして別名に分けなきゃ
100 :
デフォルトの名無しさん :2012/08/05(日) 01:55:45.56
>>97 getなんてメソッドを使ったらいけないってこと?w
プログラムで仕様が一意ならいいだろうよ
102 :
デフォルトの名無しさん :2012/08/05(日) 01:57:36.66
>>99 君、もしかして今、動的型付け言語の場合は
名前空間が違っていても、クラス名が違っていても
同一のメソッド名を作ったらいけないって言ったの?
置換するときに、間違って置換してしまうから。
103 :
デフォルトの名無しさん :2012/08/05(日) 02:00:36.19
名前空間なんか、本来名前がかぶっても大丈夫な仕組みなのに、 動的言語の場合だと、名前被らないようにしないといけないんだw
>>102 同じメソッドを再利用するためだろ
例えばtoString()を全然別の仕様で作っていいと思ってる?
それなら何も言わないけど
105 :
デフォルトの名無しさん :2012/08/05(日) 02:02:01.17
>>104 toStringに限った話なんかするな。
>>103 メソッドの仕様に関してはそうだよ。そのおかげで再利用性が高まる。
107 :
デフォルトの名無しさん :2012/08/05(日) 02:03:30.05
メールクラスのsendと HTTP通信のsendじゃ 名前一緒でも別に仕様だろうに。
108 :
デフォルトの名無しさん :2012/08/05(日) 02:04:33.07
>>106 再利用できないものを
再利用する意味は何ですか?
>>105 なんでもいいけど、じゃconcatで。
110 :
デフォルトの名無しさん :2012/08/05(日) 02:06:16.78
>>109 配列をconcatするのと
文字列をconcatするのは
別の仕様であるべきですよ。
>>107 違うなら別名にすべきでしょ。
同じ名前にするなら同じにしなきゃ。
余談だけど、HTTPのsendとメールのsendは同じでいいと思う。
>>108 具体的にどういうケースを言ってんのかわかんない
112 :
デフォルトの名無しさん :2012/08/05(日) 02:08:58.15
もっと具体的に言うと、 Array.concat (実際にActipnScriptに存在する)と String.concat というメソッドがある。 Array.concatなんて名前が変だろ! ということで、Array.joinに変更しようと思った。 String.concatまでString.joinにしていいのか?
>>110 受け取る型が違うならconcatArrayとconcatStringでいいでしょ
ただ、型を除けば違う仕様にしちゃダメだよね。ちなみに仕様ってのは
入りと出の事ね。中身がどうなっていようが問題はないから。
114 :
デフォルトの名無しさん :2012/08/05(日) 02:10:18.78
> 受け取る型が違うならconcatArrayとconcatStringでいいでしょ え? 動的型付け言語に型なんてないよ?
115 :
デフォルトの名無しさん :2012/08/05(日) 02:12:04.10
動的型付け言語言語だと Array.concatArray String.concatString にしろということらしいw Mail.sendMail HTTP.sendData かねぇw
>>112 ActionScriptって型付きじゃん
C#みたいに動的型もできるハイブリッドじゃあるけど
117 :
デフォルトの名無しさん :2012/08/05(日) 02:15:31.13
メソッド名が同じなら、同じもの扱いで 名前を変えるときは、全部変えちまえっていうのは やっぱりだめだな。 名前が同じでも、違う人っているんだよ。
>>115 そうだよ。ほれ。
てかリファクタリングから話しそらしてないか。
// 結合
NSMutableString * string = [NSMutableString stringWithString:@"aaa"];
NSString *joined = [string appendString:@"bbb"];
// 配列で結合
NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", nil];
NSString *joined = [array componentsJoinedByString:@","];
//配列に分割
NSString * string = [NSMutableString stringWithString:@"aaa,bbb,ccc"];
NSArray *record = [string componentsSeparatedByString:@","];
>>107 同じ仕様でよくね
var mail = new Main( "
[email protected] " );
mail.setSMTPHost( "smt.example.com", 1234 );
mail.setText( contet.text );
var post = new HTTP( "www.example.com", "POST" );
post.setPair( "text", contet.text );
<input type="radio" onClick="sender=mail"/>
<input type="radio" onClick="sender=http"/>
<input type="button" onClick="sender.send();" />
>>118 100歩譲って「動的言語の場合だと、名前被らないようにしないといけない」のを受け入れた
として、人間、特に複数人で開発していると間違ってかぶってしまうのは避けられないよ。
その時に、間違いを修正するために「リファクタリング」するんだが、理解してるか?
Strings.appendをStrings.appendとArrays.appendに分離する Strings.appendをStrings.appendとStrings.concatに分離する appendStringをappendStringとappendArrayに分離する appendStringをappendStringとconcatStringに分離する (このconcatとかArrayへの分離に意味があるのかは置いといて) 手法としては結局変わらないな。シグニチャを見て適切な名前か確認したり 周りの処理を見て適切な名前か判断したり。動的型か静的型でも同じ手間だね。
動的型固有かもしれないけど具体的でもっといい例があった appendをappendObjectとappendStringとappendArrayに分離する
appendArrayは要らなかったな
・Stringという仕様要件を要求するconcatStringメッセージを定義していた ・一部concatStringメソッドを実装していながらStringという仕様要件を必須としないメソッドが現れた ・それらの要件仕様をByteSequenceという要件仕様で切り出す事にした ・ByteSequence用にconcatByteSequenceメッセージを新たに定義 ・Stringが要件としてどうしても必要なのかByteSequenceで十分なのか確認しつつ 各メッセージの書き換えとメソッドの移譲を定義していく よくあるシナリオだとこんな感じだな
125 :
デフォルトの名無しさん :2012/08/05(日) 10:43:21.97
動的言語でメソッド名が被らないようにするってのは バッドノウハウでしか無いな。 やはり、リファクタリングしやすいのは静的言語ってことだな。
名前が被らないようにするのはクラス名だろと関数だろうと同じ事 被らないようにするのは今に始まった話じゃない WindowsでもUnixでも内部で一意になるよう管理してる どこがバッドノウハウなんだ?
Javascriptみたいにメンバー関数なやり方をメッセージ&メソッド方式の言語でも押し通そうとするから辛いんだよ メッセージはプログラムの空間に属するもの、メソッドはオブジェクトに属するもの そもそもそういう考えもない人が動的型ガーって言ってるんだから、そういう人にはリファクタリングは無理だわ
静的型付信者は今のところまともな反論一つ出来てない。 多分動的型付でGUIがあるような規模の開発したことすら無いんだろうな。 引き出し(ノウハウ)が少なすぎる。
129 :
デフォルトの名無しさん :2012/08/05(日) 11:27:49.59
動的言語はやっぱりダメってことだなw
>>128 >静的型付信者は今のところまともな反論一つ出来てない。
フィルターかかった目で見るとそうなんだろうな…、チーン
静的型支持してるやつで具体的な例を言えたのは
>>112 だけだね
>>112 みたいに具体的に踏み込んだ話をだせればもっと追い込めるのにね
実例を殆ど挙げられず机上の空論だけで満足してるらしいもんな
そのうえ頭の中は
>>130 みたいにフィルターが掛かってせいだと思いたいらしい
フィルター掛かってると思うならどこのレスがフィルターに消えたか示したらいい
どうせ机上の空論しか出てこないだろ
133 :
デフォルトの名無しさん :2012/08/05(日) 11:54:14.69
実際に開発してみれば、名前が被らないようにするってのは 大変なことだってわかる。 開発人数多いし、他人が作ったライブラリ使うし。 で、それがわからんのは、実戦経験がないから、 実戦経験があるとしたら、いつも1000行未満の 使い捨ての小さいプログラムを書いてるだけの人だろう。 動的言語が大規模アプリには向かないと言われるのはそのため。
Objective-Cはちゃんと維持してるし 4人〜7人レベルの開発ならレビューで指摘があって リファクタリングすることになるが? COBOL開発してた所で働いてんの?
>>133 経験から具体例を上げてくれるか?
まさかいろんな型の引数をaddObjectとか作らずadd一つで
対処してるような派遣だらけの現場じゃあるまいな
>>133 コーディングルールとか教育とかしてないの?
C++つかってたらテンプレートはダメ
JavaならJava5以降の機能は使うなって環境?
137 :
デフォルトの名無しさん :2012/08/05(日) 12:09:27.42
>>135 Object.addObjectって冗長すぎだろwww
138 :
デフォルトの名無しさん :2012/08/05(日) 12:11:40.65
Rubyのライブラリを見ると ここで話していた、ダメなメソッド名 ばっかり見つかるよな。
動的型付なんだから当たり前 冗長だと思うんなら静的型付言語だけ使ってなさい
140 :
デフォルトの名無しさん :2012/08/05(日) 12:13:54.88
>>132 >>112 の回答書いてから言えよ。(w
そういうのを無視するから、フィルターとか言われてるんだろ。
まともに大規模なライブラリ維持してるのはObjective-Cぐらいだからな
>>138 結構いろんなライブラリに
>>137 みたいな名前の奴があって、何でこんな冗長なんだ?
と常々思っていたけど、世の中こんなアホが結構居るんだな。
まあ、作った人は賢くてこの手のアホが混乱しないように配慮してるだけかもしれないが。
146 :
デフォルトの名無しさん :2012/08/05(日) 12:19:37.57
動的言語は冗長だからな。 メソッド名は被らないようにしないといけない。
147 :
デフォルトの名無しさん :2012/08/05(日) 12:20:40.25
selectメソッドって(動的言語にとっては) ダメなメソッド名の一例だね。
>>141 concatStringとconcatArrayをまず定義するから
そういう事にはならないし受け取るものが違うのに
concatって同じ名前をつけるのが間違ってるって
話でしょ。そういう場合はconcatリファクタリングして
分けると。
149 :
デフォルトの名無しさん :2012/08/05(日) 12:24:53.68
>>148 オーバーロードって知ってる?
受け取るものが違うけど、
同じ名前をつける時に使う機能。
>>146 冗長なのはそのとおりだけど静的型付けと比較した話でリファクタリング関係ないよね
151 :
デフォルトの名無しさん :2012/08/05(日) 12:27:36.29
例えば二人が別々に似ている用途の ライブラリを作ったとしよう。 当然メソッド名も似ているものができてしまう。 しかし、この2つのライブラリには 互換性がない。すなわち交換可能じゃない。 ならば、交換可能ではないと、 検知できたほうがいいだろう?
>>149 add(Object object)
add$Object
add(String object)
add$String
マングリングされると結局同じだよね
暗黙的にやってるか明示的にやってるかだけの話で
154 :
デフォルトの名無しさん :2012/08/05(日) 12:29:54.13
>>150 リファクタリングの話をすれば、
concatStringとconcatArrayを定義していたとしても、
本当にconcatStringは自分だけが使っているものか?
という判断ができないから置換が難しいってことだな。
concatという名前をつけるのが間違っていたとして
同じようにconcatStringという間違った名前をつけているものが
他にもあるかもしれない。
どうやってもその保証ができない。
>>151 2つのライブラリーでcomponentsJoinedByStringが定義されました
どう別々の仕様にできる?
156 :
デフォルトの名無しさん :2012/08/05(日) 12:30:40.85
157 :
デフォルトの名無しさん :2012/08/05(日) 12:32:41.39
>>155 名前空間とクラス名が違っていれば、
メソッド名が同じでも別々の仕様だろ?
静的言語なら、別々の仕様にできる以前に、
最初から別々の仕様になってる。
158 :
デフォルトの名無しさん :2012/08/05(日) 12:34:31.33
名前空間が作られた目的を考えれば、 どうしても同じ名前はできてしまうってことだろ?
>>156 全部Int型ならaddIntだろうし、違うなら[writeBytes:array, sizeInt:10 ]になるだろ
write$Byte[],intとなってんのを考えればすぐ判るんじゃない
160 :
デフォルトの名無しさん :2012/08/05(日) 12:37:54.74
>>159 全部Int型ならaddIntだろうし、
Int型とString型とInt型だったら
addIntStringInt ってこと?
動的言語って欠陥あるなw
>>157 クラスの実装はともかくとしてインターフェース側の仕様は統一できるように
しないといかんだろ
あとたらればじゃなくcomponentsJoinedByStringをどう別の仕様にするか具体的に書いてみて
>>154 静的型付でも同じでしょ
正しいかどうか結局考えなきゃいけない
>>144 どこに?
人には具体的にという割には、自分は全然具体的に書かないんだな。
>>145 「冗長」の意味わかってる?
Object.addObject なら、Object.add だけでいいだろ、追加するだけなんだから。
>>152 違うよ、計算機がやるかプログラマがやるか話。
プログラマは楽しようよ。
>>160 Cとかメンバー関数の存在しない言語で大規模開発した経験とか無いと辛いだろうね
>>162 いいや、静的に正しいかどうかは「計算機」が決められるから、プログラマは考える必要が無い。
166 :
デフォルトの名無しさん :2012/08/05(日) 12:42:30.85
>>161 じゃあ、条件をはっきり提示しろ。
Aというクラスに、componentsJoinedByString があった。戻り値は数値だ
Bというクラスに、componentsJoinedByString があった。戻り値は配列だ。
これらは名前が同じだが、クラス名が違うので当然仕様は別だ。
同じにしたいなら、同じインターフェースを継承するだけのこと。
ここまではいいか?
>>163 >>148 に書いてあるし同じ内容がいままでずっと出てたろ
脳内フィルターもいい加減にしろよ
>>164 昔話したいなら「昔のPC」板にでも行けよ。
て言うか、そんなもの持ち出さないといけなくなるほど、追い詰められたのか?(w
>>166 戻り値ない名前なのに言語のコーディング規約違反じゃん
170 :
デフォルトの名無しさん :2012/08/05(日) 12:45:14.11
>>164 > Cとかメンバー関数の存在しない言語で大規模開発した経験とか無いと辛いだろうね
したことがあればわかると思うけど、
たとえばGTKライブラリ。
gtk_window_new みたいに、
頭に、gtkというプリフィックスをつける。
当たり前だけど、addIntみたいに、型名をメソッド名に入れたりはしない。
>>167 >>148 >> concatって同じ名前をつけるのが間違ってるって
これがフィルターだって言うの。
静的側から見たら、全然間違ってない。
172 :
デフォルトの名無しさん :2012/08/05(日) 12:46:04.33
>>169 どこに戻り値ないと定義されているんだ?
>>168 クラス名は名前空間省略できるけど重複したら限定名使って一意の名前にしないとダメっすねぇ〜
174 :
デフォルトの名無しさん :2012/08/05(日) 12:47:16.04
>>173 だから一意の名前になっているから大丈夫ですよね?
>>171 動的型のリファクタリングの話してる時におかしいだろうが
177 :
デフォルトの名無しさん :2012/08/05(日) 12:49:20.77
C言語風に従えば、 Array.concat ・・・ 間違い Array.concatArray ・・・ 間違い Array.array_concat ・・・間違い Array.array_concatArray ・・・正解 ってことか。 あ、動的言語の場合ね。
>>170 一意になるように管理してるって話だろ?
179 :
デフォルトの名無しさん :2012/08/05(日) 12:55:31.84
たとえば、動的言語で正しい名前の付け方は var es = doc.getElementsByName(name) こんなのだよ。名前を使って複数のエレメントを 返すってことが明確になっている。 これが静的言語ならこうなる。 Element[] es = doc.get(name) getという短いメソッド名でありながら 代入先の変数の型から、getが何を返すのかわかるし、 引数の型を見てオーバーロードできる。 もちろん、型情報が存在するから間違ったコードは自動的に検出できる。
>>175 動的と静的の比較なんだが、理解できてないのか?
>>177 別のパラダイムなんだから当然でしょ。
静的型のメンバー関数な書き方から抜け出せないなら静的型を使う。
>>180 リファクタリングの仕方の問題なんだから
それぞれの特徴に合わせた話をしないと行けないだろ
静的型付言語に動的型付言語のリファクタリングを強要してリファクタリングしづらいとか
動的型付言語に静的型付言語のリファクタリングを強要してリファクタリングしづらいとか
言ってもそりゃしづらいねで終わるわ
183 :
デフォルトの名無しさん :2012/08/05(日) 13:04:14.45
>>182 リファクタリングというのは、間違ったコードを直すという面も大きい、
つまり、間違えることが前提になっているから
間違いしなければ大丈夫って発想じゃダメなんだよ。
そこわかってる?
>>179 最初はフォームチェックぐらいしか想定してなかったから
Java風を取り入れた大規模に向かない名前が多かったけど
Javascriptもこういう名前の付け方増えてきたね
185 :
デフォルトの名無しさん :2012/08/05(日) 13:05:17.16
まあ、将来性を考えたうえで、 汎用的なメソッドの名前にするか そのクラス専用のメソッド名にするかなんて 決められるわけ無いよな。 未来のコトはどうなるかなんてわからんのだし。
>>182 それを言い出したら、どっちもどっちでそれこそ終わりだろ。
すくなくとも、名前の被りをプログラマが気にしないといけない動的と、
計算機が管理してくれる静的を比べたら、静的のほうがマシだろ。
特に大規模を経験したことあれば、「人が管理できる」なんていうのは
幻想だとわかるはず。
188 :
デフォルトの名無しさん :2012/08/05(日) 13:07:28.52
管理しているつもりで ミスしているかもしれないしなw ミスがあるのがわかったとしても、 ミスがないことを保証してくれないのだから どんだけチェックしても不安は拭えない。 あ、動的言語の話。
>>186 OSXは幻想か?
WindowsのWM_XXは幻想か?
派遣や短期雇用だらけとか管理体制が悪いだけじゃないの
190 :
デフォルトの名無しさん :2012/08/05(日) 13:08:56.22
わかりやすく言えば、 「名前をちゃんと分けておかなければならないだろ!」 に対する反論は 「人間誰でもミスはするもんだろ!」 で終わりってことだな。
191 :
デフォルトの名無しさん :2012/08/05(日) 13:10:06.96
>>189 プロジェクトで使っている
メソッド名一覧を作れって話?
>>188 >>166 の話も中途半端に終わったがそのミスってなんだ?
間違いならリファクタリングで直すだろ
194 :
デフォルトの名無しさん :2012/08/05(日) 13:11:33.40
> 間違いならリファクタリングで直すだろ その直す手間が 動的言語では大変だって話。 話ちゃんと理解してる? なんで、直すだろ。で終わるんだよ。
195 :
デフォルトの名無しさん :2012/08/05(日) 13:12:05.01
> 規約とレビューとリファクタリング それをやりやすいのは静的型付け言語です。
・名前を一貫できない→リファクタリングしろ
・名前のリファクタリングが難しい→
>>121
198 :
デフォルトの名無しさん :2012/08/05(日) 13:15:59.70
たとえば、concatArrayとうメソッドがあったとする。 この文字列をgrepで検索して使用している所が多く見つかったとする。 そしてconcatArrayの定義も複数見つかった。 なぜか複数のクラスで定義されている? のちにこれは間違いだったとわかるのだが、 さて動的型付け言語で、この間違いを見つけるのにどれだけ時間がかかるだろうか。 ちなみに、静的型付け言語では、特定のクラスのconcatArrayだけを 検索できるので、間違いを見つけるのも修正するのも簡単です。
199 :
デフォルトの名無しさん :2012/08/05(日) 13:18:50.10
>>196 Strings.appendをStrings.appendとArrays.appendに分離する
Strings.appendをStrings.appendとStrings.concatに分離する
appendStringをappendStringとappendArrayに分離する
appendStringをappendStringとconcatStringに分離する
問題はここから
全ソースの中から、すでに使用されているappendを調べあげ、
それがStringsに属するものかArraysに属するものか判断しないといけない。
data.append これをどちらに直せばいいのか
コードを読まないと判断できない。
200 :
デフォルトの名無しさん :2012/08/05(日) 13:20:34.67
リファクタリングは定義を直せば終わりだって思ってる 愚か者が多いってことだな。 使っている場所すべてを直さないといけないのに。
>>198 >>49-56 に出てた話だよね
動的型付なら複数異なる実装が間違って同じインターフェースを実装してんのと同じ話ってね
同じインタフェースを継承してる箇所は全部チェックするけど静的型だろうが
動的型だろうが手間は変わらない
202 :
201 :2012/08/05(日) 13:24:21.42
間違えた。 動的型付なら全て同じインターフェースを実装してるわけで 静的型付言語で言うなら複数異なる実装が間違って同じインターフェースを実装してんのと同じ話
203 :
デフォルトの名無しさん :2012/08/05(日) 13:24:23.96
204 :
デフォルトの名無しさん :2012/08/05(日) 13:25:01.36
>>201 同じインタフェースを継承してる箇所は全部チェックするけど静的型だと
インターフェースのメソッド名を選んで、検索するだけで
すぐに見つかるよねw
205 :
デフォルトの名無しさん :2012/08/05(日) 13:27:42.10
>>202 > 静的型付言語で言うなら複数異なる実装が間違って同じインターフェースを実装してんのと同じ話
OK。間違ったとしよう。
静的型付け言語なら、インターフェースを実装する前に、
「○○インターフェースを実装します」と書いてあるはずだ。
class ×× implements ○○ みたいに。
ならそれをclass ×× implements △△ に変更すれば良い。
あとは、どのメソッドがおかしいかをコンピュータが教えてくれる。
静的型付け言語は、リファクタリングしやすい。
>>199 data.appendはappendStringとappendArrayに分離する
Strings.appendをStrings.appendとArrays.appendに分離するのと
どう手間が違うんだい?Strings.appendもArrays.appendにしていいか全て調べないと行けない
>>121 以前の話に戻りたいの?
207 :
デフォルトの名無しさん :2012/08/05(日) 13:29:11.00
>>202 間違っているものを、直すまでが
リファクタリングです。
その直すまでの手間の話ですよ。
なんでリファクタリングの話してるのに
間違いを見つけただけで話を終わらせるの?
208 :
デフォルトの名無しさん :2012/08/05(日) 13:29:48.71
>199 の、問題はここから が本題なのに、 なんでそこ無視するんだよw 問題はここから 全ソースの中から、すでに使用されているappendを調べあげ、 それがStringsに属するものかArraysに属するものか判断しないといけない。 data.append これをどちらに直せばいいのか コードを読まないと判断できない。
209 :
デフォルトの名無しさん :2012/08/05(日) 13:31:03.43
>>206 > data.appendはappendStringとappendArrayに分離する
お前アホw
data.appendは定義じゃねーぞ。
func foo(data) {
data.appned
}
みたいな話だ。
分離するってなんの話をしてるんだよw
210 :
デフォルトの名無しさん :2012/08/05(日) 13:33:11.97
これがわかりやすい 198 名前:デフォルトの名無しさん[] 投稿日:2012/08/05(日) 13:15:59.70 たとえば、concatArrayとうメソッドがあったとする。 この文字列をgrepで検索して使用している所が多く見つかったとする。 そしてconcatArrayの定義も複数見つかった。 なぜか複数のクラスで定義されている? のちにこれは間違いだったとわかるのだが、 さて動的型付け言語で、この間違いを見つけるのにどれだけ時間がかかるだろうか。 ちなみに、静的型付け言語では、特定のクラスのconcatArrayだけを 検索できるので、間違いを見つけるのも修正するのも簡単です。
211 :
デフォルトの名無しさん :2012/08/05(日) 13:34:15.60
動的言語だと、間違って名前かぶらせてしまった違うものを 分離するのが大変。
>>208 静的型でも読まなきゃ判断できないって書いたけど?
Arraysは置き換えてないんだから静的型付でも自動で調べようがないじゃん
213 :
デフォルトの名無しさん :2012/08/05(日) 13:34:48.49
>>209 ---before---
func foo(data) {
data.appned
}
func bar(data) {
data.appned
}
---after---
func foo(data) {
data.appnedString
}
func bar(data) {
data.appnedArray
}
215 :
デフォルトの名無しさん :2012/08/05(日) 13:36:32.44
静的型付け言語なら、dataがStringかArrayかは 静的に決まってるんだから、自動で判断できるだろ。 もしかして、コンパイラを使う言語で メソッド名を変更して、コンパイルエラーが起きた所を 直すってことやったことない? コンパイラ使った開発してる人は、 普通にやったことあると思うんだどなぁ。
>>213 じゃコード書いて、ここに自動チェックが入るとか示してみてよ
このままじゃ堂々巡りになりそう
217 :
デフォルトの名無しさん :2012/08/05(日) 13:37:31.19
>>214 ---before---
func foo(data) {
data.appned
}
func bar(data) {
data.appned
}
■ ここにかかる時間に着目しましょうwww ■
---after---
func foo(data) {
data.appnedString
}
func bar(data) {
data.appnedArray
}
218 :
デフォルトの名無しさん :2012/08/05(日) 13:39:41.67
>>216 静的言語であればこうなってるはず
---before---
func foo(String data) {
data.appned
}
func bar(Array data) {
data.appned
}
■ ここにかかる時間に着目しましょうwww ■
・Stringクラスのappedを変更。
・Arrayクラスのappedを変更。
作業は本当にこれだけこれだけ
↓これはコンピュータが全部自動でやってくれる
---after---
func foo(String data) {
data.appnedString
}
func bar(Array data) {
data.appnedArray
}
---before--- func foo(Arrays data) { data.appned } func bar(Arrays data) { data.appned } ■ ここにかかる時間に着目しましょうwww ■ ---after--- func foo(Strings data) { data.appned } func bar(Arrays data) { data.appned }
220 :
デフォルトの名無しさん :2012/08/05(日) 13:41:15.52
222 :
デフォルトの名無しさん :2012/08/05(日) 13:42:36.37
>>219 の例では変更する手間は同じ
>>218 の例では静的型付け言語のほうがやりやすい。
総合点は・・・静的型付け言語の勝ちですね
>>220 動的型のインターフェースと静的型のインターフェースの関係がわからないんだねw
224 :
デフォルトの名無しさん :2012/08/05(日) 13:43:27.82
動的型付ならインターフェースの識別はメソッド名に付く 静的型付けならインターフェースの識別はクラス名になる
226 :
デフォルトの名無しさん :2012/08/05(日) 13:45:07.50
228 :
デフォルトの名無しさん :2012/08/05(日) 13:50:53.21
>>225 そんなことはどうでもよくて
変数に型情報がついているか(型付け)か
どうかが重要だよ。
静的型付け、動的型付けの話をしているのだから。
変数に型情報がついているから
その変数の型の宣言(定義)を変えると、
すべての変数を追跡可能になる。
つまり、obj.foo() のfooのを変更する、すなわちobjの型MyObjを
変更すると型情報から文字列比較ではなく意味的に関連がある
コードを見つけ出すことが出来る。
>>226 1つのインターフェース名動的型付けと静的型付で分離して比較する問題で
>>218 では、静的型ではインタフェース名に当たらないメソッド名を変更してるからな
func foo(String data) {
data.appned
}
func bar(Array data) {
data.appned
}
動的型付げんごなら↑状態は
そもそも↓の状態だ
func foo(data) {
data.appnedString
}
func bar(data) {
data.appnedArray
}
230 :
デフォルトの名無しさん :2012/08/05(日) 13:53:13.72
>>225 って型付けの意味がわかってないんじゃないか?
それじゃ、違いはないと勘違いするのもわかるねw
>>228 どうでも良くはない
リファクタリングの比較にならんだろ
232 :
デフォルトの名無しさん :2012/08/05(日) 13:55:11.29
>>229 話を戻すな。先に進めろ馬鹿。
動的型付け言語では、appendという名前が悪いって話だろ。
で、appendStringという名前に変えたいんだよ。
その名前を変える時の手間の話だ。
お前、なんもわかっとらんじゃないか。
233 :
デフォルトの名無しさん :2012/08/05(日) 13:56:57.46
>>231 どうでもいいのは
> 動的型付ならインターフェースの識別はメソッド名に付く
> 静的型付けならインターフェースの識別はクラス名になる
これのこと。
リファクタリングに差があるのは、型付け。
つまり、変数名の型。
変数に入っているオブジェクトの識別は
動的型付け言語だと実行時に行われる。
だから実行前に行うリファクタリングと相性が悪い。
>>229 はちょっと語弊があるな
正確にはこんな感じか
func foo(StringAppendable data) {
data.appned
}
func bar(ArrayAppendable data) {
data.appned
}
--------------------------
func foo(data) {
data.appnedString
}
func bar(data) {
data.appnedArray
}
235 :
デフォルトの名無しさん :2012/08/05(日) 13:58:52.11
200 名前:デフォルトの名無しさん[] 投稿日:2012/08/05(日) 13:20:34.67 リファクタリングは定義を直せば終わりだって思ってる 愚か者が多いってことだな。 使っている場所すべてを直さないといけないのに。
>>232 何が違う?静的型付のインターフェース名を分割するのと
動的型付のメソッド名を分割するのは同義だろ。
func foo(String data) { data.appnedString } func bar(Array data) { data.appnedArray } 動的型付にこんなふうにインターフェース情報に更にインターフェース情報を 追加しなきゃいけないってな対になる概念はないからな 静的型付言語だけでよろしくやってくれよとしか言い様がないな
238 :
デフォルトの名無しさん :2012/08/05(日) 14:03:16.39
>>236 だから、その作業を行う手間が違うって話だろ。
何度言えば理解できる?
240 :
デフォルトの名無しさん :2012/08/05(日) 14:08:43.41
>>239 お前卑怯だな。
他に大きく変わる例をわざと無視して、
変わらない例だけを持ちだしてきて
変わらないという結論にしようとしてるだろ
見え見えだ。
>>219 の例では変更する手間は同じ
>>218 の例では静的型付け言語のほうがやりやすい。
総合点は・・・静的型付け言語の勝ちですね
>>240 >>218 は静的型付言語の勝ちでいいんじゃない?
動的型付言語には対応するものが無いんだから不戦勝だよ
242 :
デフォルトの名無しさん :2012/08/05(日) 14:11:00.73
>>239 はIDE使ったこと無いんじゃないか?
コンパイラ技術を使って名前ではなく
確実に同じメソッドであると判明したものが
自動的に書き換わるという体験をしたことがないだろう?
ソースコードをテキストエディタで
ちまちま書き換えるだけじゃないんだよ。
まぁ意味ないしなw
245 :
デフォルトの名無しさん :2012/08/05(日) 14:12:37.47
>>241 前提条件で、appendを
appendStringとappendArrayに書き換えるという話。
なぜなら、動的型付け言語にとっては、appendという名前は
おかしいから。
これを忘れてないか?
>>242 動的型付言語の同じメソッドは、全てインターフェースを持ってるって事がすぐ頭から飛ぶよね
>>242 例えばstringWithStringを検索したら
stringWithStringメソッドを実装したオブジェクト全ての呼び出しと考えられるけど。
あとXCodeでObjective-Cのリファクタリング機能使ってみたら?
249 :
246 :2012/08/05(日) 14:31:09.53
>>245 型云々インタフェース云々の事情を無視して
文字通りappendにStringとArrayを付けたいだけ
なら静的型付言語の方が楽なんじゃないかな
リファクタリングじゃなくて名前変えてるだけに見えるけど
nominalな静的型付け言語、例えばJavaとかに毒されると こんなにアホになるんだという見本だな。 ていうか、お前等暇人だな。こんなアホ相手に延々議論しちゃって。
>>137 >Object.addObjectって冗長すぎだろwww
この辺のレスみると頭の硬さが滲み出てて面白いよなぁ
実際呼び出すときArray.addObjectかもしれないし
List.addObjectかもしれない。夏の匂いがする
>>252 >実際呼び出すときArray.addObjectかもしれないし
>List.addObjectかもしれない。
これが静的 (リファクタリング時) にわかるかどうかだろ。
Array.addObject だけ変更したい時に、静的なら IDE にお任せすることが出来るけど、
動的だとどうやるんだい?
254 :
uy :2012/08/05(日) 19:11:23.56
まーたリファクタリングの意味勘違いしてるやつが
255 :
uy :2012/08/05(日) 19:14:41.08
リファクタリングの定義を
書籍「リファクタリング―プログラムの体質改善テクニック」から
抜粋してやるからしっかりと理解するように。
http://d.hatena.ne.jp/tbpg/20120316/1331922781 リファクタリングする理由
設計の向上
バグの発見
開発スピードの向上
可読性の向上
品質の向上
リファクタリング自体は新たな機能を追加するものではないので、
開発スピードの向上というと矛盾しているように聞こえるかもしれません。
長期的にみれば、よりよい設計が維持されているソースコードは追加・修正の
工数が下がるためトータルで費やす工数は減ることになります。
障害対応の工数も減りますし。
256 :
uy :2012/08/05(日) 19:15:37.66
257 :
uy :2012/08/05(日) 19:16:54.96
http://d.hatena.ne.jp/tbpg/20120320/1332248019 書籍 リファクタリング−プログラマーの体質改善 | メソッドの構成
リファクタリング
パンくず
リファクタリング-プログラマーの体質改善テクニック
メソッドの構成
内容
メソッドの構成
リファクタリング名 対象 対応
・メソッドの抽出 1つにまとめられるコードの断片がある コードの断片をメソッドにして、その目的を説明する名前をつける
・メソッドのインライン化 メソッドの本体が名前と同じくらいわかりやすい メソッドの本体を呼び出し元の本体に組み込み、メソッドを削除する
・一時変数のインライン化 単純な式で1度だけ代入されている一時変数があり、その一時変数が他のリファクタリングの邪魔になっている
その一時変数に対するすべての参照を取り除き、式にする
・問い合わせによる一時変数の置き換え 一時変数を使って式の結果を保存している 式をメソッドにする。一時変数のすべての参照箇所を式に置き換える。
新しいメソッドは他のメソッドからも使える
・説明用変数の導入 複雑な式がある 処理の目的を説明するような名前を持つ一時変数に式、または式の一部の結果を代入する
・一時変数の分離 ループ変数でも計算結果の蓄積用の変数でもないのに、複数回代入される一時変数がある 代入ごとに別々の一時変数を用意する
・パラメータへの代入の除去 コードが引数に代入を行っている 代わりに一時変数を使う
・メソッドオブジェクトによるメソッドの置き換え 「メソッドの抽出」を適用できないようなローカル変数の使い方をしている長いメソッドがある
メソッドを独自のオブジェクトに変え、すべてのローカル変数がそのオブジェクトのインスタンス変数になるようにする。こうすれば、メソッドを分解して、
同じオブジェクトの別のメソッドにすることが可能になる
・アルゴリズムの取り替え アルゴリズムをもっとわかりやすいものにしたい メソッド本体を新しいアルゴリズムで書き換える
258 :
uy :2012/08/05(日) 19:17:50.05
オブジェクト間での特性の移動 リファクタリング名 対象 対応 メソッドの移動 メソッドが、自分のクラスよりも他クラスの機能を使ったり、他クラスから利用されたりする。 今はそうでなくても、そうなりつつある。 メソッドをもっともよく使っているクラスに同じ内容の新メソッドを作る。 古いメソッドは、このメソッドに処理を委ねるか、完全に取り除く。 フィールドの移動 メソッドが、自分のクラスよりも他クラスの機能を使ったり、他クラスから利用されたりする。 今はそうでなくても、そうなりつつある。 ターゲットクラスに新しい属性リーダーを作り、フィールドを使っているコードを書き換える。 クラスの抽出 2つのクラスで行うべき仕事をしている1個のクラスがある。 新しいクラスを作成し、 関連フィールド、メソッドを旧クラスから新クラスに移す。 クラスのインライン化 クラスが大した仕事をしていない。 すべての機能を他のクラスに移して、クラスを削除する。 委譲の隠蔽 サーバに委譲を隠すためのメソッドを作る クライアント側がサーバー側のパラメータについて知っていると両者の依存度が高くなります。 サーバー側のオブジェくトを返却する小さい委譲メソッドを用意することで、この依存を無くすことが出来ます。 仲介人の除去 クラスが単純な委譲をやり過ぎている。 クライアントに委譲オブジェクトを直接呼び出させる。 外部メソッドの導入 利用中のサーバクラスにメソッドを追加する必要があるが、そのクラスを変更できない クライアントクラスに、 サーバクラスのインスタンスを第一引数に取るメソッドを作る 局所的拡張の導入 利用中のサーバクラスにメソッドをいくつか追加する必要があるが、クラスを変更できない それらの追加されるメソッドを備えた新たなクラスを作る。この拡張クラスは元のクラスのサブクラスまたはラッパーである
259 :
uy :2012/08/05(日) 19:19:31.64
データの再構成 リファクタリング名 対象 対応 自己カプセル化フィールド オブジェクトによるデータ値の置き換え 値から参照への変更 参照から値への変更 オブジェクトによる配列の置き換え 観察されるデータの複製 単方向関連の双方向への変更 双方向関連の単方向への変更 シンボリック定数によるマジックナンバーの置き換え フィールドのカプセル化 コレクションのカプセル化 データクラスによるレコードの置き換え クラスによるタイプコードの置き換え サブクラスによるタイプコードの置き換え State・Strategyによるタイプコードの置き換え フィールドによるサブクラスの置き換え
260 :
uy :2012/08/05(日) 19:20:21.11
条件記述の分解 複雑な条件文(if-then-else)がある 条件部、"then"部、"else"部からメソッドを抽出する。 条件記述の統合 同じ結果になる条件テストが複数並んでいる それらを1つの条件式にまとめ、メソッドとして抽出する 重複した条件記述の断片の統合 条件式のすべての分岐に同じコード片が含まれている その部分を式の外に出す 制御フラグの削除 一連の論理式で使われる制御フラグとして機能している変数がある 代わりにbreakやreturnを使う ガード節による入れ子条件記述の置き換え 正常な実行経路がはっきりしないような条件分岐を持つメソッドがある すべての特殊条件をガード節で処理する ポリフォーフィズムによる条件記述の置き換え オブジェクトのタイプによってふるまいを変える条件文がある 条件文の分岐先をポリモーフィックに呼び出せるオブジェクトのメソッドに移す ヌルオブジェクトの導入 コードの中でnull(nil)値のチェックを繰り返している null(nil)値の代わりにnullオブジェクトを導入する 表明の導入 プログラムの状態について何らかの条件を前提としているコードがある アサーションによって、前提条件を明確に表現する
261 :
uy :2012/08/05(日) 19:20:54.96
メソッド呼び出しの単純化 リファクタリング名 対象 対応 メソッド名の変更 メソッドの名前がその目的を正しく表現できていない メソッド名の変更 引数の追加 あるメソッドが、呼び出し元からより多くの情報を必要としている その情報を渡すために引数を追加する 引数の削除 ある引数が、もはやメソッド本体から使われていない。 引数を削除する 問い合わせと更新の分離 1つのメソッドが値を返すと同時にオブジェクトの状態を変更している 問い合わせようと更新用の2つのメソッドをそれぞれ作成する メソッドのパラメータ化 複数のメソッドが、異なる値に対してよく似た振る舞いをしている。 その異なる値を一つの引数として受け取るメソッドと作成する 明示的なメソッド群による引数の置き換え 引数の特定の値によって異なるコードが実行されるメソッドがある 引数の値に対応する別々のメソッドを作成する オブジェクトそのものの受け渡し あるオブジェクトから複数の値を取得し、それらの値をメソッド呼び出しの引数として渡している 代わりにオブジェクトそのものを渡す メソッドによる引数の置き換え あるオブジェクトがメソッドを呼び出し、その戻り値を別のメソッドの引数として渡している。受信側は、そのメソッドを呼び出させる 引数を削除し、 受信側にそのメソッドを呼び出させる 引数オブジェクトの導入 本来まとめて扱うべき一覧の引数がある それらをオブジェクトに置き換える setメソッドの削除 フィールドの値が生成時に設定され、決して変更されない そのフィールドに対するすべてのsetメソッドを削除する メソッドの隠蔽 メソッドが自分の定義されているクラス意外からまったく使用されていない そのメソッドを非公開にする Factory Methodによるコンストラクタの置き換え オブジェクトを生成する際に、単純な生成以上のことをしたい ファクトリメソッドを使って、コンストラクタを置き換える ダウンキャストのカプセル化 メソッドが返すオブジェクトが、呼び出し側によってダウンキャストされる必要がある。 そのダウンキャストをメソッド内に移動する 例外によるエラーコードの置き換え メソッドがエラーを示す特別なコードをリターンしている 代わりに例外を発生される。 条件判定による例外の置き換え
262 :
uy :2012/08/05(日) 19:21:36.05
継承の取り扱い リファクタリング名 対象 対応 フィールドの引き上げ 2つのサブクラスが同じフィールドを持っている。 そのフィールドをスーパークラスに移動する。 メソッドの引き上げ どのサブクラスでも同じ結果になるメソッドがある。 メソッドをスーパークラスに移す。 コンストラクタ本体の引き上げ 複数のサブクラスに内容がほとんど同一のコンストラクタがある。 スーパークラスのコンストラクタを作成して、サブクラスから呼び出す。 メソッドの引き下げ スーパークラスのふるまいが、一部のサブクラスでしか使われない。 メソッドをサブクラスに移す。 フィールドの引き下げ スーパークラスのふるまいが、一部のサブクラスでしか使われない。 フィールドをサブクラスに移す。 サブクラスの抽出 クラスが一部のインスタンスだけしか使わないメンバを持っている。 それらのメンバのためにサブクラスを作る。 スーパークラスの抽出 同じような機能を持つ2つのクラスがある。 片方のクラスをスーパークラスにして、共通するメンバをスーパークラスに移す。 インタフェースの抽出 複数のクライアントが、あるクラスのひとまとまりのインタフェースを使っている。または2つのクラス間でインタフェースの一部が共通である その共通部分をインタフェースとして抽出する 階層の平坦化 スーパークラスとサブクラス(またはモジュールとそのモジュールをインクルードするクラス)に大差がない 両者を1つに統合する Template Methodの形成 サブクラスがスーパークラスのインターフェイスの一部しか使っていない、あるいはデータの継承を望まない スーパークラスのためのフィールドを作り、スーパークラスに処理を委譲するようにメソッドを調整してから、継承構造を解消する 委譲による継承の置き換え サブクラスがスーパークラスの一部のインターフェースだけを使っている。あるいはデータを継承したくない スーパークラス用のフィ0ルドを作成して、メソッドをスーパークラスに委譲するように変更し、継承をやめる 継承による委譲の置き換え 委譲を使っているが、インターフェイス全体のために多数の委譲メソッドを書いている 委譲先のクラスをモジュールにして、委譲元のクラスでインクルードする
263 :
uy :2012/08/05(日) 19:22:09.39
継承の取り扱い リファクタリング名 対象 対応 継承の分割 同時に2つの仕事をしている継承階層がある 2つの階層を作り、片方からもう片方を実行するには委譲を使う 手続き的な設計からオブジェクトへの変換 手続き型のスタイルで書かれたコードがある データレコードをオブジェクトに書き換え、ふるまいを分解してオブジェクトに移す ※詳細記事なし プレゼンテーションとドメイン分離 ドメインロジックを含んでいるビュー、コントローラクラスがある ドメインロジックはモデルに移す ※詳細記事なし 階層の抽出
>>253 Eclipseで名前変更した時みたいになる
265 :
uy :2012/08/05(日) 21:30:45.12
266 :
uy :2012/08/05(日) 21:33:52.78
動的型付け言語だと、Eclipseを使っても 静的型付け言語ほど、正しい変更は行なってくれないよ。
>>253 >Array.addObject だけ変更したい時に、静的なら IDE にお任せすることが出来るけど、
どこにそんな素敵なIDEがあるんだろ
Eclipseなんかはインターフェース共有してたらまるごと変更されるし
NetBeansか他の環境かな?
268 :
uy :2012/08/05(日) 21:46:26.53
> Eclipseなんかはインターフェース共有してたらまるごと変更されるし 最初っから、インターフェース共有してない場合の話だよ? その場合、どうなる?
>>253 Eclipseでjava.util.Listを実装してるクラスのメンバーを個別に置き換えられないように無理だよ。
全て同じインターフェース実装してるようなもんだから。
同じインターフェース継承してるクラスのメンバー名書き換えと動作は同じ。
270 :
uy :2012/08/05(日) 22:11:19.88
>>269 逆だろ?
個別に変えるんじゃなくて
全部変えたいんだよ。
たまたま、バグやミスで
同じ名前になっているものを
除いてね。
271 :
uy :2012/08/05(日) 22:15:47.91
全部変えるなら、動的型付け言語でも静的型付け言語でも 一個一個変えて行かないといけないのは同じだろう?
272 :
uy :2012/08/05(日) 22:24:13.50
いや、静的型付け言語なら定義を一箇所変えるだけで 同じ名前で違うものを除いて、 全て自動でに変えてくれる。
interface ObjectHolder { ObjectHolder addObject( Object object ); } これを実装してるクラスのaddObjectを個別に名前変更するにはどうしたらいいか それを議論したほうが有用だな。動的型付言語にも応用が効くだろう
274 :
uy :2012/08/05(日) 23:51:36.48
> これを実装してるクラスのaddObjectを個別に名前変更するにはどうしたらいいか 個別に実行するのはなんのため? リファクタリング = 動作を変えない変更 ってことは当然知っているよね?
引用元:Scalaプログラミング入門(p.3) RubyとRailsのプロジェクトが数千行の規模を超え、チームに新しいメンバーを追加したときに、 動的言語の問題が明らかになって来ました。私たちは、コーディングの時間の半分をテスト作成の 費やさなければならなかったのです。 Railsによって得られた生産性の向上は、テスト作成の作業に失われてしまいました。 作成したテストの多くは、Javaであれば不必要なものでした。テストの大半は、 リファクタリングによってメソッド名やパラメータの数を変更した際に、 呼び出し元が正しく変更されているかを確認するためのものでした。
>>275 このソースは「型推論を備えた関数型言語」であるScalaの優位性を
説明するのには適しているけど、単なる静的型付け言語の優位性を
説明できていないよね
なぜって、Rubyから移行したのは「Javaではなく」Scalaなのだから....
この書籍の著者は、なぜ「型推論の無い手続き型言語」であるJavaへ
移行しなかったんだろねwww
結論は「Ruby(静的型付け) >> Java(動的型付け)」だろ
つまり型推論の無い静的型付け言語はゴミってことさ
277 :
276 :2012/08/07(火) 17:53:15.39
いけね、肝心な所を間違えた
訂正する
>>276 X: >結論は「Ruby(静的型付け) >> Java(動的型付け)」だろ
O: >結論は「Ruby(動的型付け) >> Java(静的型付け)」だろ
馬鹿だな Scala(静的型付け,型推論) >> Java(静的型付け) >> Ruby(動的型付け)
リファクタリング関係ないんだからよそでやれ
Javaはうんこすぎる シェアも下がって来てるし完全にオワコン
>>279 >テストの大半は、リファクタリングによって
GUI周りはPythonに占拠されて結局デスクトップには出て来なかったね Androidもそのうちnaclベースになるだろうし衰退が加速してるな
社畜ドカタPGにまともなプログラムを作らせる観点から見れば プログラミング言語は使用ユーザー数 ライブラリ数 つまり、宗教 優秀な人材集めての少人数や、一人で何かを開発するならば自分らが最も使いやすい言語、 普通それは"動的言語"になる。 確実にね いっておくが、本当に速度が必要になるケース以外で そこんところにC#だのJAVAだの来るってのは大抵何かを間違ってるか ただ環境を整えられる知識がないだけ 実は速度の問題に関しても、問題になる部分のみをCでかいてライブラリ化して動的言語から扱うのが一番良い 技術さえあるなら動的言語1択
>普通それは"動的言語"になる。 確実にね いいえ
C# とか Java に挫折したアホでしょ、スルー推奨。
というのがこの板のレベル・・・
わざわざドカタ用に設計されたJavaで挫折するって 適正無さすぎだから論じるに値しない
そういう発想がドカタなのです ドカタより下は残念ながら存在しません あなた方が最底辺なのです
>>283 動的言語というとlispやRoot上でのC++か。
290 :
uy :2012/08/09(木) 21:23:01.47
>>288 Javaが土方用の言語の理由って何?
わかりやすい、生産性が高い
ってのはメリットだと思うが。
291 :
uy :2012/08/09(木) 21:31:49.31
動的型付け言語っていうのは コードに書くべき情報を省略できる言語。 書くべき情報ってのは型情報なわけだが。 省略できるから一見開発効率がいいように思えるかもしれないが、 静的型付け言語ならコードを見ればわかった情報がわからないということでもある。 自分一人で書いたようなコードなら、情報が欠落していても、 覚えてるかもしれないが、他人が書いたコードを読むときは困る。 コード全体を探索して変数に何が入りうるか 調べないといけないし、それがわかってコメントに、 「この変数は○型です」なんてかこうものなら 静的型付け言語使えよという話になる。
だからいってるだろう 動的言語は1人 or 少人数(優秀) での開発に限ると 逆に1人で開発するにもかかわらず、静的言語で開発するメリットはない 自分で書いたコードの型情報なんて流石に覚えてるだろう ただ覚えきっている情報を常に見て書いて間違わないように組み立てなきゃいけなくなるだけ 妥協しても、せめて型推論が強い言語だろう 1人での開発において 動的 or 型推論 以外はありえない ただのあふぉ
偽uyに100ペリカ
偽だから一人でも静的使うってことか。 誰だよこんなコード書いたの。先月までの俺とは別人だぜ。
>メリットはない >間違わないように組み立てなきゃいけなくなるだけ
296 :
デフォルトの名無しさん :2012/08/10(金) 00:37:39.18
馬鹿には無理
297 :
デフォルトの名無しさん :2012/08/10(金) 00:46:25.89
動的言語の利点はだれでもしっている しかし動的言語での開発でおこりえる難題については実際にやらないとわからない そう、わからないはずで上辺しか知らないはずなんだよ 知ったかすぎる
組み方云々はどうでもいいからリファクタリングの話しろよ
299 :
uy :2012/08/11(土) 01:29:35.80
リファクタリングの話をすると、
それはリファクタリングじゃないとかいうやつがでてくるからな。
正直うざい。
リファクタリングの定義。
>>255-263 少なくともこれらはリファクタリングで間違いない。
うわ長文の連投うざ
301 :
デフォルトの名無しさん :2012/08/12(日) 16:04:35.47
あげ
レスファクタリング
type1_obj.add1(); type2_obj.add(); type2_obj.add1(); この時、type1型のadd1をaddにリファクタリングしようとすると・・・ type2のadd1までaddに書き換わってメソッド名が重複する。 うわぁ。
>>303 そういうしょぼい { 環境 | 言語 | 知能 } 使ってる人は、マ辞めた方がいい。
動的言語って変数名変えただけで全てテストしないといけないからな
スペルミスが実行時バグとして炸裂するオモチャ言語なんぞスレ違いだろ!!!
動的型言語は、A::method() と B::method() の呼び出しが静的に区別できないので、 リファクタリングには向いて無いわ。
>>303 変わっちゃ困るなら始めから同じ名前にするな
Objective-CやPharo系の様にリファクタリングして重複しないよう管理しろ
309 :
uy :2012/08/15(水) 01:14:58.46
動的言語で大規模開発してる奴らも世界には沢山いる そういう奴らは少なくともスキルは低くない
310 :
uy :2012/08/15(水) 02:01:44.57
静的型付け言語で大規模開発してる奴らも世界には沢山いる そういう奴らは少なくともスキルは低くない
>>308 type1とtype2がまったく関係なく
それぞれ違う人が書いてたらどうすんの?
それとも一人で作るのが前提なのか?
>>311 リファクタリングして統一
サードのライブラリーなら別リンケージに置いて隔離
また言語標準を無視してるものは避ける
言葉たらずだったんで訂正 >サードのライブラリーなら別リンケージに置いて隔離 >また言語標準を無視してるものは避ける サードのライブラリーなら言語標準を無視してるものは避ける どうしても必要なら別リンケージに置いて隔離
314 :
uy :2012/08/16(木) 21:23:44.02
確かにメソッド名の変更とかが容易ではないのは認めるよ だから最初は少し必要以上に長く名前を付けてどこともかぶらないようにする あとからよく設計を考えて使いやすい名前にailiasする って感じのことを俺はやってる
315 :
デフォルトの名無しさん :2012/09/13(木) 00:46:52.09
PharoとかSmalltalk系の環境はいいな SenderやらImplementerボタン一発でメソッドに依存するメッセージや メッセージ送りつけてるクラスを列挙してくれる インタプリターが使える言語もインタプリター自体に リファクタリング機能搭載すりゃコンパイラー向け言語とは 比べ物にならん恩恵を得られるんだろうにな
Smalltalkはコンパイルがメソッド単位なのとソースがメソッドの属性扱いなのと スタックフレームがファーストクラスオブジェクトなのがサイコー。 おかげで、デバッガで実行中メソッドのソース修正してそのまま続行とか楽勝なのがイイッ!
317 :
uy :2012/09/13(木) 20:33:49.39
キリッ
318 :
デフォルトの名無しさん :2012/09/13(木) 20:41:09.28
単に実行するまでエラーが出ないというだけで プロジェクトの規模が大きくなるほど幾何級数的に効率が落ちていくのは自明だと分かりそうなもんだけど。 ちゃんとTDDすればいい(キリッ じゃねーだろ。解決になってねーから。 計算機科学の知見も完璧無視だしさー なんなんですかね、この最近の動的言語ブーム。 やはり悪の権化JavaScriptが間違って覇権言語になっちまったせいですか?
実行時エラーは静的型言語でも排除できないから結局テストは必要だし 型付きでできることだけに頓着してりゃ安全なのは当たり前だってそろそろ気づけよ。 逆に動的型で静的型と同じ制限された事しかしないならどうやったって非効率
リファクタリングはテストするのが大前提なんですが
>>316 そこら辺に書いたソースの切れ端をdo itで即座に実行できるじゃん
あれって特にコンパイル単位ってきまってないんじゃないか?
>>318 処理系自体がリファクタリング機能をもった環境つかってみな。
コンテキストを処理系自体が理解してるってのは大きく違う
一度でも使ったことがあるならそんな発言しなくなるだろう
>>321 do it とか print it っていうのは、評価対象のコードをメソッドとして
コンパイルして、そのコンテキストの self のクラスに DoIt というメソッドとして
追加して、あらためて self に対して DoIt というメッセージを送るということを
やっていたりします。
処理は全てブロックですと言ってしまえば確かにそりゃそうだけど・・・
>>324 はどのレスの何をうけてブロックがどうとか言っているの?
メソッドとしてコンパイルしてるって話。
うん、だから、ブロックの話はどっから出てきたのかなって。
Smalltalkのブロックはメソッドの部分実行で実現されている。 処理はすべてメソッドってんならわかるんだけど、あえてブロックと言い換えた 理由がちょっと分からなくて。メソッドと書くつもりでブロックと書いてしまったとか?
>>328 アセンブリレベルで考えたら何でも処理ブロック単位じゃん。
実装レベルで堀下げて行けば結局〇〇でしょってパターンになるよねって言いたかったの。
高レベル、概念的なレベル、人間が知覚してるレベルで言えばソースの切れ端が
コンパイル&実行されてる感覚じゃない?
>>330 > ソースの切れ端がコンパイル&実行されてる感覚
んーと。君の考えるSmalltalkにおいて、ソースの切れ端(do itされるコード片?)は
メソッドオブジェクト(CompiledMethodのインスタンス。実体はバイト列)以外の何に
“コンパイル”された後に実行される感覚が高レベル、概念的なレベル、人間が知覚してる
レベルで自然なのかを教えてもらえたりできる?
ソースの切れ端がコンパイルされてると受け取るのが 高レベル、概念的なレベル、人間が知覚してるレベルで自然だと思うよ どう実装されてるか低レベルな部分なんてどうでもいいしね 低レベルな実装はライブラリーによって変わるし もしかしたら、インタプリター実行する実装もあるかもしれない ましてや、SqueakやPharoとか自分で書き換えられるわけで 低レベルの実装なんてどうでもいいじゃん
ソースの切れ端がコンパイルされてアセンブルレベルの処理ブロックになっているとか そんなイメージってこと?
実装はともかくイメージはね
いみじくも
>>332 で例として挙げられている、Smalltalkの処理系がユーザーの手で
書き換えてどんどん変化させられるという特性は、処理系を可能なかぎり低レベルまで
Smalltalk自身で表現することで、ユーザーがそれを積極的に学べるようにする工夫の結果ゆえ
http://bit.ly/aOCyGy なので、「低レベルとか実装なんてどうでもいいじゃん、
言語処理なんかアセンブルレベルの処理ブロックに帰結できるし、実際にもそういう
イメージで十分だし不都合は感じない」ってスタンスで処理系に接している人には
>>316 みたいのをメリットとして共感や実感はされにくいだろうなと分かった
こういう奴がスパゲッティプログラムを作るんだろうな…
あんなもんメリットでも何でもないから 後に生まれた言語では「あえて」外されてる Gotoがあったら便利、とか言ってるアホと同じ
オープンクラスにおけるモンキーパッチの弊害とかと混同していない? そもそも、リファクタリングのアイデアやそれをサポートする機能は Smalltalkにおいて、処理系の特性や仕組みを理解し自分の手でどんどん改善したり、 ソースはもちろんコンパイルされたコードもオブジェクトとして扱える環境があって 育まれえたわけで、いちがいにSmalltalk独自の動的性というのは害悪ばかりではないよ
Lispマクロの繁用による弊害と一緒 可読性を下げる
>>337 言語のユーザーに徹するスタンスからはそうなんだろうけど、
一方で、せっかく動的でリフレクティブな性格をそこそこ備えた
PythonやRubyとかの言語であっても、あるいは静的型だけどオブジェクトの動的性は
Smalltalkに非常に似たものを持っているJavaなどの言語でも、
Smalltalk程度のリファクタリング機能やデバッグ機能の実装が必要以上に複雑になったり
そもそも実現自体が困難になってしまっているという残念感もある。
>>335 多分俺とは視点が違うね。
オブジェクトに対しメッセージを送るとき、そのオブジェクトは何者であるかあまり期待しない。
俺はそれの延長線として低レベルはどうでもいいと思ってる。
あと、インタープリターといったのは処理系自身というより、Smalltalk上でインタープリターと
して実現されてたらという話。機械語レベルの話は例として出してただけでそっちに執着してるわけじゃない。
重要なのは実装はどうでもいいってとこ。
君は、Smalltalkがライブラリーで物理的に実装してる事をいいたいんだろう。
んで、実際の実装はメソッドを使ってる事が多いからメソッド単位でコンパイルされてると
理解するのが当然だといいたいんだろ。そんで、その処理方法は公開されてるから誰でも見られる。
単に、今のライブラリーの実装・未変更な状態の実装なら確かにそうだろう。
ただ、オブジェクトにメッセージ doIt )を送る側としてはどうでもいいのよ。
>>339 ソースの書き換えの話をしてるならマクロとは全然違うぞ
Linuxのソースを修正するのと変わらん
皆が好き勝手にパッチあてた俺俺Linux そんなもんの上で動かしたコードがバグったとき どこがオカシイか調べるのが大変なのは馬鹿でも分かる
それすらやったことの無いアホが抜かしおる
まあ玩具専用言語だからね 玩具はいろいろ弄れた方が楽しいだろ?
国内はIBMが「VB >>>> Smalltalk」と証明してしまったのが大きい
玩具専用とか言っている奴はSqueakとかせいぜいPharoしか知らんのかと。
単に日本人向きじゃないのと、日本語資料が少なすぎるからだけだろ 英語圏の人間ならSmalltalk環境起動さえしてしまえば、使えるから殆どマニュアルは要らん なのでマニュアル類自体も少ない、
>>348 あれはCincom SmalltalkとGemStone/SでやろうってったところにIBMが自社製品の
VisualAge Smalltalkをごり押ししてきてめちゃくちゃにした結果で、VBは漁夫の利。
VBごときであっさり作れるもんで あんなに揉めてたのが驚き
今Smalltalkを普及させるならどうしてもWebへの親和性が必要だろうな
Seasideとかしらんの?
>>352 火消しでVBごときで済ませたモノと、当初の予定が同じだと思っちゃうオツムの弱さに驚き
ちげーよ。Webへの親和性はあるけど、それは普及のカギじゃねーよって話し。
>>355 とにかくオブジェクト指向技術で作りたかったんですよね
オブジェクト指向技術で作る事にメリットがあるとか、そういう理由じゃなくて
歴史的にみれば、オブジェクト指向は役に立ったから Smalltalkはゴミだった、ってことだよね
日本語のライブラリリファレンス書いて公開すりゃいいんじゃね
Smalltalkが普及する世の中って逆に怖いな。 こういうのは滅びない程度に秘密兵器的に使われてTraitsとかClassboxesとか ときたまその中の頭のいい人が新機軸を打ち出してくれるのがいいのであって
>>360 違うよ。火消しの頃にはもうオブジェクト指向とかどうでもよくなってて、
DBのフロントエンドをVBで書いただけ。
>>360 が当初の予定を書いてると読み取れないオツムの弱さ
Smalltalkは実質関係ない九大事件なんかより、 ケント・ベックがなんやかや偉そうなことを言ってても、 けっきょくCOBOLをSmalltalkで置き換えられなかった話しのほうが Smalltalkダメダメじゃん的エピソードとしてパンチがあると思うんだがなぁ…
Cobolの置き換えなんて不可能だって皆知ってたから
>>366 どんな言語でも完全に置き換えられてないと思うが。
それは別としてその話どこに書いてある?どんな見解か読みたい。
あと、VB vs Smalltalkな話も読んで見たいんで誰かソース教えて。
>>363 そしてRubyとかPHPとかあたりがありがたくパクるというエコシステム
> 日本IBMは7月20日になってようやく,協力会社に対して「ジェムストーンとの交渉決裂は, > 企業(日本IBM)の根幹にかかわる問題のため」と説明した。関係者によると,契約の条文に > 「(システムのユーザーなどが)何らかの理由でジェムストーンを訴えた場合, > メイン・コントラクタ(主契約者:もし日本IBMがジェムストーンと契約を結ぶ場合には日本IBM) > がすべての法的な対応を行わなければならない」という内容が含まれており,日本IBMがそれに納得できなかったためという。 > 料金面でも折り合わなかったようだ。ジェムストーンのコンサルタントが九大病院に滞在したのは3カ月だが, > コンサルタント8人の経費やソフト・ライセンス料などで,数億円近くを要求したとされる。 カス過ぎワロタ
Smalltalkのあまりのウンコさに絶句 滅びて本当に良かった
あんな単純な言語の学習失敗してアンチになるやつってどんな低脳なの?
ググリ力も半端なく貧弱で VisualWorksのチュートリアルにすら辿り着けてない奴だよきっと
単純な言語だからこそ、学習難易度が高くて使い手が減ったのではなく 他言語と比べてあまりにもゴミだったから使われなくなったと そういうことですね、分かります
使ってないのは、MSやらSunのステマに弱い日本だけだけどな。
開発実績数じゃねぇのにそんなの真に受けてんのかよw 検索回数とWeb上の記事数とかで出した値を真に受けるとか高校生かよ
> GitHub’s rankings are based on GitHub’s own stacking of the individual languages
Smalltalkってそもそも言語じゃないからな よく話に出てるのは、Smalltalk系ツールの中で使われてるスクリプト用?言語(むしろシェル?)。 言語じゃなくPharoとかVisualWorks、Squeakなんかが出てくる資料で調べないと意味がない。 bashとかzshで調べるよなもんだ。
>>381 Smalltalk系はソースコードで管理してないからGitHub使えんだろ
極一部例外としてGNU Smalltalkってマイナー環境があるけどマイナーすぎる
ほらGitHubなんかに上げてる奴殆どいないだろ Smalltalk系はイメージで管理する独自のリポジトリーがあるからな 普通そっち使うわ
ショボっ
1万も無いけどHTTP用リポジトリも結構使われてるんだな。用途が判らんけど。
まあ絶滅した言語ならこんなもんでしょ 古いゴミばっかりだけど
標準的な技術を使わず 独自仕様で囲い込みに走るのは ヘボい技術全般の特徴
Borlandが衰退してからDelphiも効かなくなったね やっぱ企業ゴリ押しかUnix likeな言語じゃないと流行らんのだろうな
393 :
デフォルトの名無しさん :2012/10/14(日) 16:38:20.44
リファクタリング前と、リファクタリング後で 動作が変わっていないことを、 確かめるツールがあるといいのに。
つテスト
395 :
デフォルトの名無しさん :2012/10/14(日) 17:04:52.35
>>394 それは人間がやらないといけないからコストがかかる。
コードの動作が同じであることは、
理論的には推論で求められるはず。
例えばコンパイラの最適化技術で、
コードの順番を入れ替えることがある。
これは順番を入れ替えても違いがないことを推論しているから。
なら逆に順番が入れ替わったコードを見て、
コードの動作が同じであることを推論できるはず。
つまり、コンピュータにさせることが可能。
397 :
デフォルトの名無しさん :2012/10/14(日) 17:57:36.95
>>396 やっぱりJavaか・・・。
動的言語じゃ不可能なんだろうね。
> これは順番を入れ替えても違いがないことを推論しているから。 > なら逆に順番が入れ替わったコードを見て、 > コードの動作が同じであることを推論できるはず。 素数の積が計算できるから 素因数分解もできるはず、レベルの暴言ですね
いや、別に全部のケースをやれなくても、50% でもやれればずいぶん助かる。 単純な名前の変更とかも結構あるでしょ?
静的というか javaだけの方が正しい
Javaはどうせ何やっても大して洗練されたコードにならないから 名前変更とかメソッドの移動なんかの 機械的にできるしょうもないリファクタリングがメインになる
402 :
デフォルトの名無しさん :2012/11/14(水) 00:27:14.28
機械的に出来るしょうもない作業を 手動でやるのはバカだと思うよw
コンパイラが勝手にテストしてくれるのに、わざわざ人間がテスト書くって馬鹿らしいよな。
コンパイラが多くのエラーを見つけてくれる言語が優れている
>>403 コンパイラが検出してくれるような部分までテスト書いてんのか?
そりゃ馬鹿らしい、というか馬鹿だわ
406 :
デフォルトの名無しさん :2012/11/14(水) 22:04:53.69
>>405 これでいいか?
コンパイラが勝手にテストしてくれるのに、わざわざ人間がテストを実行するのって馬鹿らしいよな
twitterがruby捨ててjavaに移った理由で、twitter社のプログラマーが、毎回引数の型チェックするコード書くのが馬鹿らしくてやってられなくなったからって、答えてたインタビューあったよな。
>>402 機械的にできるしょうもない作業を手動でやってたのが静的型土方w
一方、動的型使いはリファクタリング技術をつくって静的型土方に与えてやったw
410 :
デフォルトの名無しさん :2013/02/20(水) 18:48:21.49
動的型付けだと途中で変数の型を変えたり出来る クラスの継承みたいなのがない これはメリットにもなるがデメリットにもなる 人間だもの、間違いだって起こすさ ソース中で誤って違う型の変数を渡したりしていても分かりにくい
411 :
デフォルトの名無しさん :2013/02/20(水) 18:50:36.10
プロなら変数の型を間違えるような そんなミスはしないとか、 テストツールを作ればいいとか言うが本当にそうかね
412 :
デフォルトの名無しさん :2013/02/20(水) 18:52:39.71
継承はコードに密結合を生むのでマジうんこ これ有り難がってる低能もマジうんこ
設計のできない低能には要らないものなんだな。
設計の観点から言えば密結合は避けた方が良いのは自明 それが分からない低能だけが継承を有り難がる
416 :
デフォルトの名無しさん :2013/02/20(水) 20:57:38.88
結局動的型付けでも型チェックは要るんだろ それが既存のツールで出来るのなら問題ないが みんな自分で作ってんの? いくら継承要らずで書きやすいって言ってもね〜
417 :
デフォルトの名無しさん :2013/02/20(水) 21:11:17.95
静的型付け言語でもmixin使うという手はあるぜ
単体試験で済ませるだろうに。 単体試験で渡す時のStab型に最低限の関数を持たせとけば良い。
>>415 静的型付でもgoを始め、継承のない言語は存在するぞ。
C++も継承はかなり避けられる。
420 :
デフォルトの名無しさん :2013/02/20(水) 21:29:45.32
>>418 単体試験に問題がない
(テストケースを全て網羅している)
という証明はどうすればいいの?
>>420 静的型付でも検査項目に漏れが発生するのは同じでしょ
意図が判らん。あと静的型付でもどのみち試験しなきゃならん。
422 :
デフォルトの名無しさん :2013/02/20(水) 22:00:20.47
>>421 そうだよ。
だから「テストを使ったリファクタリングのリグレッションテスト」は
信用出来ないわけ。
つまり、テストを使わないでリファクタリングの
修正の安全性を担保する方法が必要になる。
そこででてくるのが、コンピュータによる静的解析で
修正の安全性を担保するリファクタリングブラウザ。
423 :
デフォルトの名無しさん :2013/02/20(水) 22:04:45.21
あとコンパイラもリファクタリングに使える。 例えば関数の引数を一つ増やした時に コンパイルすれば、修正が必要な箇所がわかる。
424 :
デフォルトの名無しさん :2013/02/20(水) 22:07:43.12
つまり加算だよね。 テストだけ VS テスト + リファクタリングブラウザ + コンパイラ たとえばテストが漏れていてリファクタリング結果に問題がるのにOKになってしまった。 こういうことは起こるわけで、 そんな状態であっても、リファクタリングブラウザやコンパイラを使ってれば問題を回避できる可能性が高い
425 :
デフォルトの名無しさん :2013/02/20(水) 22:24:08.62
>>408 Twitter社の中心プログラマーのスキルが低いとは思えないけど。
>>422 静的解析なら動的型付言語でもできるじゃん。
ちょっと動的型付と言うには違和感あるけどSmalltalkとかね。
>コンパイルすれば、修正が必要な箇所がわかる。
試験実行すれば修正が必要な箇所が解るよ。
そもそも試験してない項目は仕様外だし。
例えば、開いていないStreamに対してRead messageを送ったけど何も読み込めなかった。
これは仕様外。負の値を受け付けない関数に負の値を渡した。これも仕様外。
427 :
デフォルトの名無しさん :2013/02/20(水) 22:33:55.51
>>426 出来るできないの話じゃなく、
どれだけ正確にできるかって話
動的型付け言語と静的型付け言語の
間には乗り越えられない大きな壁がある。
428 :
デフォルトの名無しさん :2013/02/20(水) 22:35:23.19
試験実行すれば修正が必要な箇所が解るよ。 その後デバッグするんだろう?w テストでエラーに成った。エラーに成ったがその原因はわからない。 いまから何が起きたのか、デバッグを行う。 静的型付け言語であれば、しなくてもいいものをする必要があるんだよな。
429 :
デフォルトの名無しさん :2013/02/20(水) 22:37:24.25
> そもそも試験してない項目は仕様外だし。 試験してない理由が、 試験漏れということもある。 試験方法が間違っている場合もある。 テストが完璧である保証は何処にもない。 100%完璧なものはないが、 より完璧に近い方法というものは存在する。
>>422 そもそもRefactorするときにSignatureを頻繁に変更するもんじゃないよ。
するなら同じMessageを受け取るClass全てを変更する必要がある。
単にひとつのClassのSignatureを変更するというならそれはRefactorじゃない。
ただの開発だ。
>>429 批判的根拠はあるの?どこかに動的型付から静的型付に変えたら
不具合がこれだけ減ったって統計が出てた?単に主観じゃないの?
433 :
デフォルトの名無しさん :2013/02/20(水) 22:44:33.65
>>431 不具合が減るんじゃなくて
リファクタリングにかかる時間が減るんだよ。
>>432 Java厨のための劣化Refactorじゃん。
そもそもRefactorはSmalltalkから始まり動的型付言語を中心に
醸成された概念だぞ。そんな劣化したRefactorじゃなく
本家のRefactorを根拠にしてくれないか。
435 :
デフォルトの名無しさん :2013/02/20(水) 22:50:00.14
> Java厨のための劣化Refactorじゃん。 なにいってんの? Smalltalkのリファクタリングブラウザに すでにこれらの機能があるんだが?
>>435 部分的にMethodやMessageを変更するRefactorなんてねぇよ。
Pharoとか本物のSmalltalkの処理系使ったことないだろ。
無知って可哀想だと思ったw
http://c2.com/cgi/wiki?RefactoringBrowser The RefactoringBrowser is a tool that automates some ReFactorings for Smalltalk.
・ExtractMethod -- make a submethod out of the selected text. If there is already an equivalent method, optionally invoke that instead.
・Inline method -- put the invoked code in place of the invocation. This even works for methods in other classes.
・Move to component -- move the code for a method to another class and invoke it
・These three together are extremely powerful. For example, if I notice.
・Add parameter -- add a parameter to every implementor of a message, and to every invocation of the message (with a Default value)
・Remove parameter -- if no implementor of the message uses the parameter, remove it from the methods and the invocations
・Cross referencing from inside the source code -- select any program element in the text and you get a choice of several specialized browsers - senders/implementors of a message, readers/writers of a variable
・Rename -- you can rename classes, variables (all types), and messages
・Abstract/concrete instance variables -- make all references to an instance variable go through a message, or make all references direct
>>433 引数を増やすとか抽象的な話じゃなく、
具体的に例を出すとどういう場合?
>>437 やっぱりSmalltalk使ったことないだろw
書いてることはEclipseなんかと似てても実際の動作は違うんだよ。
>>438 > 引数を増やすとか抽象的な話じゃなく、
それ具体的じゃね?w
>>439 使ったことがあるのなら「実際の動作が違う」ということを
具体的にかけるはずだよ。
ほら、書いて証明してみせてよw
継承による抽象化で密と疎を使い分けられないとは。 なんでも疎結合とかいってコストかけるだけの設計なら楽でいいな。そんなの実装するような土方にはなりたくないけど。
部分的にMethodやMessageを変更するRefactorなんてねぇよ。 ↓ ・Add parameter -- add a parameter to every implementor of a message, and to every invocation of the message (with a Default value) ・Remove parameter -- if no implementor of the message uses the parameter, remove it from the methods and the invocations ↓ 似てても実際の動作は違うんだよ。 ↓ 今からSmallTalk版のAdd parameter, Remove parameterの 説明をしてくれるそうです
マーチン ファウラーのリファクタリングだとコンパイラによるチェックができるところでは コンパイラでの型チェックを積極的に使ってるよね
>>438 文字列を受け取るMethodに範囲を引数として追加する必要が発生したとか。
>>441 既に書いたじゃん。部分的な変更は出来ない。全体で変更する。
もっと具体的に言うともうひとつの方法として、変更加えるClassのみ変更するってのがある。
引数や戻り値で受け取ったobjectに対するMessageは全てのClassのobjectが受け取る可能性があるからね。
446 :
445 :2013/02/20(水) 23:09:32.47
447 :
デフォルトの名無しさん :2013/02/20(水) 23:11:24.71
> 既に書いたじゃん。部分的な変更は出来ない。全体で変更する。 どういうこと? Eclipseが部分的な変更だっていうの? 「Smalltalkが全体で変更する」で「動きが違う」ってことは Eclipseは部分的な変更しか出来ないってことになるが? 部分的な変更ってなんだよ。 お前にしかわからない用語を使わないで ちゃんと説明しろ。
448 :
デフォルトの名無しさん :2013/02/20(水) 23:14:10.83
もともとはこういう話だったはずだが? > そもそもRefactorするときにSignatureを頻繁に変更するもんじゃないよ。 結局、SmalltalkでもSignatureを変更するんじゃん。
>>443 object := something selector:arg.
object example.
例えば、上みたいなどの型でobjectが得られるかわからない状態だと、
exampleに引数を追加してはいけない。もしexampleに引数を追加するなら全てのclassに対し引数を修正する必要がある。
だから、部分的な修正というのはない。修正せず新しくSomethingの戻り値を使用するMethodを追加する。
もうひとつの方法として説明したのは、あるobjectはあるClassのinstanceであると解る場合。
object := Type new.
object example.
この場合は、Refactoring Browserで自動で修正できる。
>>448 矛盾はしてないでしょ。頻繁にはしない。影響範囲が大きくなりがちだから。
451 :
デフォルトの名無しさん :2013/02/20(水) 23:29:00.49
影響範囲が大きくても 影響範囲が把握できるなら 何の問題もないでしょ? それに影響範囲が大きくても やらなきゃいけないわけで。
そもそも色んな言語で非推奨関数が存在する事を考えれば、 そう安易にSignatureの変更できない事なんて解ると思うけどな。
453 :
デフォルトの名無しさん :2013/02/20(水) 23:31:07.20
> そもそも色んな言語で非推奨関数が存在する事を考えれば、 それは単に、関数の作成者と 使用者が違うからだよ。
大抵は違うでしょ。そんな小規模でRefactorすんの?
それは別としても30箇所以上で使用しているClassのMethodなんかを安易に変更するか? そもそも、その修正はそこまで重要か?Smalltalkなんかの巨大なLibraryだとあくまで、 Methodの追加で済ませるのが定石。Signatureを修正するのは最後の手段だぞ。
どうでもいいがSmalltalkのリファクタリングブラウザーは動的解析するぞ。 動的型付言語なんだからやっぱりリファクタリングツールも動的になる。
457 :
デフォルトの名無しさん :2013/02/21(木) 04:00:33.99
>>454 プロジェクトローカルでないものって意味だよ。
ようは使ってる人が把握できないから
古い関数を残す。
誰も使っていないとわかれば
それは必要ない。
458 :
デフォルトの名無しさん :2013/02/21(木) 04:02:42.31
>>455 > それは別としても30箇所以上で使用しているClassのMethodなんかを安易に変更するか?
数は関係ない。(変更前のものを)誰も使っていないとわかればそれは要らない関数消していい。
誰も使っていないことを把握してからやるから、これは安易な変更ではない。
どうやって(動的型付け言語で)誰も使ってないことを証明するんだよ?と
聞かれれば、そりゃ静的型付け言語の方がリファクタリングしやすいって話だからねぇ。
ということになる。
キーワード引数とデフォルト引数が無い言語では 引数増やしたら便利だなーってなったら(当然、増やさなくても動く。リファクタリングなんだから) ソースコード全部を変更して廻るんだよ クローズドな小規模開発なら、それでもいいかもね
静的厨って唯我独尊なんだなw 静的型で可能なリファクタリングと 動的型で可能なリファクタリング、 どっちが種類が豊富だと思う?
>>458 そもそも何で関数消しまくったりするハメになるの?
ちなみに、動的型付言語でも誰も使ってない関数を消すことは簡単だけど。
呼び出しを変更するのは難しいけどね。
>>457 誰も使ってないinterfaceのメンバー関数を消すのは簡単でしょ。
動的型付言語でも呼び出しの一切ないメソッドやらメンバー関数を消すのは簡単。
メッセージ送信が存在しないことを調べりゃいいだけだもんね。
そうでなくても、全ての制御経路を走査して使用していないメソッドやらメンバー関数を
見つける動的リファクタリングツールなんてのもある。
463 :
デフォルトの名無しさん :2013/02/21(木) 21:48:13.21
>>460 クラスがない言語であれば
メソッドの引き上げなどがないから
言語仕様が多いほど種類は増える。
だけどその場合メソッドの引き上げじゃなくて、
メソッドの移動という名前になるだけで
本質的に違いはない。
動的と静的で変わるのは、リファクタリング
するときにかかる時間。これが大きく違う。
どちらもリファクタリングツールを使った場合どれぐらい時間が変わるんだい?
465 :
デフォルトの名無しさん :2013/02/21(木) 21:53:40.69
>>462 > 動的型付言語でも呼び出しの一切ないメソッドやらメンバー関数を消すのは簡単。
問題は「呼び出しの一切ないメソッドやらメンバー関数」を
どうやって探すかだよ。
Javaであれば、コンソールに使用されていない変数などが表示される。
コンパイラの力を借りれば、使用されていないかどうかがわかるという仕組み。
仮に使用しているメソッドを削除したら、コンパイル時にエラーが出る。
これと同じ事が動的言語で出来るのかといえば、
できなくはないが、時間が大きくかかる。
466 :
デフォルトの名無しさん :2013/02/21(木) 21:55:40.33
>>464 > どちらもリファクタリングツールを使った場合どれぐらい時間が変わるんだい?
例えばSmalltalkであれば、実行して該当行に来ないと
リファクタリングツールは利用できないことがある。
ツールを使ってからの時間であれば、どちらも大差ないが、
そのツールが利用できるようになるまでの時間が違う。
さらにツールが利用できない場合すらある。
それが動的言語だと顕著に多い
>>457 プロジェクトローカルなら、セレクターとメソッド一括置換すりゃええんちゃうの?
外部ライブラリーと仕様が異なるなら、そのメソッドは外部ライブラリーと違う名前にリファクタリングしときゃえんちゃうの?
後で外部ライブラリー追加してセレクターの名前が重複しそうになった時も、外部ライブラリーのセレクター記述する前に、
プロジェクトローカルなセレクターとメソッドの名前を重複しない名前にリファクタリングしときゃええんちゃうの。
468 :
デフォルトの名無しさん :2013/02/21(木) 22:15:08.26
> プロジェクトローカルなら、セレクターとメソッド一括置換すりゃええんちゃうの? 全く同じスペルだけど意味が違うものがあったらどうするんだ? スペルが同じ=全く同じもの。という言語は少ないだろ? 例えばgetとかいうメソッドを全部get_by_nameに置き換えていいと思う? コメントも入れれば更に大変なことになるだろうし。
リファクタリングできるのは自前のコードだけなんだから、 自前のコードは一意に管理しとけば十分でしょ。 リファクタリングの都合以前に、動的型付言語でOOを活かすなら 常に、一意になるように管理しとかなきゃいけない。 それがリファクタリングが必要な理由の一つでしょ。
470 :
デフォルトの名無しさん :2013/02/21(木) 22:18:20.98
最初っから正しい名前をつけていれば問題ないんだけど 間違った設計を正すのがリファクタリングだからな。 だからリファクタリング前の前提として、今の状態が間違っている。というのがある。 間違いだから、どんな間違いだって犯すさ。
471 :
470 :2013/02/21(木) 22:19:40.52
ちw 先読みして書いたつもりだが、10秒遅れたか。 一意になるように管理しとかなきゃいけない? そうだとしても、間違えてしまったんだからしょうがないだろ。 間違ってるのを直すのがリファクタリングだ。
外部のライブラリーのセレクターを書く前に直せばいいだけだから、 それまでの間にいくら間違っても問題ないよ。 それと外部ライブラリーとの干渉のチェックぐらいは自動化させときゃいい。 そもそも、ある程度なれたプログラマーならそういうチェックは習慣になってなきゃ。 そうじゃないと、OOを上手く生かせない。
つか言語によっちゃメソッド以前にクラス名が衝突せんか確認するのは常識だもんな 名前付きインポートなしで、オーバーライド不可な言語なら、外部ライブラリとの名前衝突は常に調べとかないと 静的型付でもgoやC++みたいな言語でもある程度同じ事を考えとく必要があるしね。
>>472 書く前に直せるのは、書く前に気づいた場合のみ。
気づいてないから間違えた。
気づいていないものをどうやって書く前に直すのか?
>>473 名前空間があるのは、
クラス名だけじゃ衝突するからだぞ?
わかってるのか?
常に名前空間省略するなというのかよ。
外部ライブラリーとのメンバーの名前干渉考えなきゃならんのは修正の範囲に差はあれどJavaも同じだわな ライブラリーのバージョン上がった時に基底クラスのメンバーを勝手にオーバーライドしたり、 新しく導入した外部のライブラリーを継承しようとしたら基底クラスのメンバーを気づかずオーバーライドしてたりとか。
>>475 名前空間が使えない言語ではって書いてるのに何がいいたんだろうね。
ぶっちゃけ名前空間が必要なのは、ライブラリー作者だけでしょ。
末端の利用者は自分で名前変えりゃいい。
他人が作ったAというライブラリと 他人が作ったBというライブラリで メソッド名がかぶっていたらどうするの?
>>476 > ライブラリーのバージョン上がった時に基底クラスのメンバーを勝手にオーバーライドしたり、
> 新しく導入した外部のライブラリーを継承しようとしたら基底クラスのメンバーを気づかずオーバーライドしてたりとか。
はい、当然それを検出するための機能がJavaにはあります。
だからさ、メソッド名やクラス名がかぶるのは 防ぎようがないんだよ。 だから、被っても問題が出ないように 言語仕様を作るわけ。 かぶったらお手上げだー かぶらないように気をつけなきゃー といってる時点で劣ってるよ。
>>479 そうですか。ありましたか。それ以前に検出できるかどうかは問題ではないんですが。
>>479 言語機能で衝突を検出する→名前を変える
ツールで衝突を検出する→名前を変える
>>480 そんな言語PL/Iぐらいしか無いだろ
名前空間のある言語は名前空間ぶつかるし。
ぶっちゃけ名前変更とか低レベルな話はどうでもいいんで、 もうちょっと具体的な話していい? これは実際にあったPythonでの開発の話なんですけど、 幾つかの関数でメモ化を使ってるのが見つかったので、 リファクタリングしてデコレータで共通化したんですよ。 @memorize def f(x, y): って感じで、@memorizeを付けるだけで関数がメモ化されるように。 こういうリファクタリングって需要あると思うんだけど、 他の言語ではどうやって書いてるのか興味あるので教えてください。マクロ?
メッセージ転送が使える言語ならメッセージ転送使うわ PharoとかObjective-Cとか。
メモ化はmemoizeだろ
>>484 低レベルというが、基本的な機能ほど
よく使うんだぞ。
そういうところに時間がかからない言語のほうが
優れてる。
つまらないことほど、はやく終わらせたいだろ?
それともソース全部みるか?
>>488 使用例
| memoizedObject |
memoizedObject := Memoizer allWith: TargetType new. "TargetTypeの全てをmemoizeする場合"
memoizedObject := Memoizer selectWith TargetType new selectSelectors: #(#method1 #method2) "TargetTypeの一部をmemoizeする場合"
memoizedObject exampleSelector.
全てをmemoizeする場合のMemoizerの実装側はこんな感じ
doesNotUnderstand: aMessage
| result |
cache having: aMessage
ifTrue:
[
^cache at: aMessage, "前の記憶した内容結果を返す"
]
ifElse:
[
"新しい結果を採取する"
result := aMessage sendTo: target.
cache put: aMessage with: result.
^result.
].
使用例が解りづらいので修正 | memoizedObject | memoizedObject := Memoizer allWith: TargetType new. "TargetTypeの全てをmemoizeする場合" memoizedObject := Memoizer selectWith TargetType new selectSelectors: #(#exampleSelector #otherSelector) "TargetTypeの一部をmemoizeする場合" memoizedObject exampleSelector:10. "MessageであるexampleSelector:10がMemoizeされる"
瑣末なミスがあったんでさらに修正 | memoizedObject | memoizedObject := Memoizer allWith: TargetType new. "TargetTypeの全てをmemoizeする場合" memoizedObject := Memoizer selectWith: TargetType new selectSelectors: #(#exampleSelector: #otherSelector:) "TargetTypeの一部をmemoizeする場合" memoizedObject exampleSelector:10. "MessageであるexampleSelector:10がMemoizeされる" doesNotUnderstand: aMessage | result | ( cache having: aMessage ) ifTrue: [ ^cache at: aMessage, "前の記憶した内容結果を返す" ] ifElse: [ "新しい結果を採取する" result := aMessage sendTo: target. cache put: aMessage with: result. ^result. ].
>>492 せっかく親切に書いてくれたのに申し訳ないのだけど、よくわかんなかった。
たとえばその方法で Integer>>#factorial をメモワイズしたい場合はどういうふうにするの?
あと、PythonのデコレーターみたいにSmalltalkならPragmaを使って実現できないのかな。
Integer >> factorial
"Answer the factorial of the receiver."
<memoize>
self = 0 ifTrue: [^ 1].
self > 0 ifTrue: [^ self * (self - 1) factorial].
self error: 'Not valid for negative integers'
といった感じで元ある定義に <memoize> を書き足すだけでいいとか。
>>465 Javaでリファレンス調べるのと同等レベルの
「呼び出しの一切ないメソッドやらメンバー関数」
ぐらい、Smalltalkでも一発でわかるけど、
一体いつの時代のSmalltalkの話をしている?70年代?
>>463 まずは静的/動的と、クラスの有無は直交した概念だということを理解してくれ。
あと、静的型では型整合のためにできない変形も
動的型では許容されるものがあることも理解してくれ。
静的型ではこれができるが動的型ではできない、というものは原理的にない。
逆に、動的型ではできる変形が、静的型では許されない、というものはある。
>>489 名前変更の手間なんて結局動的型付だろうが、静的型付だろうが
普通に運用してりゃ手間は変わらんって話が出たろうに。いつまでも粘着すんな。
> 名前変更の手間なんて結局動的型付だろうが、静的型付だろうが > 普通に運用してりゃ手間は変わらんって話が出たろうに。いつまでも粘着すんな。 手間は変わるぞ? まず、名前の単語を選んで変換するだけで 正確に変更できるるやり方を教えてくれ。 困ってるんだ。PHPとJavaScriptとRubyで。 あるクラスのgetを違う名前に置き換えたいんだ。 でも、data.get()のdataがなんのクラスかわからないから この場合のgetを置き換えていいかどうかわからないんだ。
getとかそんな名前付けるなんて糞プログラマーじゃん 基本的なリファクタリングすらしてこなかったのかよ救いようがねぇな
>>498 get全て変えればいいんじゃね。同じ名前ってことは同じ仕様って事だろw
501 :
デフォルトの名無しさん :2013/02/22(金) 22:37:20.49
平凡な能力のプログラマーが大半を占めるのが現実だからね。趣味で一人でプログラム書いてるんなら、勝手にすればいいと思うけど。
静的型言語厨はなぜ初歩的なリファクタリングができないのか
>>499 糞だからリファクタリングで直すんだろw
お前ちょっとわかってない。
interface Aのメソッド名を変えよう あら大変、名前を変えてみたら既にいくつかの 派生クラスが同じメソッド名つかってたわ! なんてことでしょう!?
手間が変わるぞ ↓ (まじだ手間が変わる。話題をすり替えないと!) ↓ そんな基本的なことも出来ないやつがバーカーバーカ ガキかw
>>504 そういうとき、動的言語だとどうするの?
静的型付け言語だと、静的に型がわかるので
data.get()とかかていても、
あー、dataは○型だね。○型のはインターフェースAを使ってるね。
インターフェースのAを変えたってことは、この箇所のdataのget()も
書き換えないといけないねって
高度な推論が可能なのに!
>>503 保守しやすくするのと、OOを最大限活かすためだが。
例えば、メソッドの名前変更。同じSignatureで意味の異なるメソッドが
存在する状態になると多態性を生かした既存のメソッドの再利用ができなくなる。
継続的に、ソースの柔軟性を保つために動的型付言語で発展してきた技術だ。
>>506 そういう状態に陥らないようにリファクタリングしとくんじゃん
>>508 どうやって?
名前を変える前に、既にいくつかの派生クラスが
同じメソッドを使っていたかどうかを
調べる方法を答えなさい。
なお、他人が作ったもので、すでに
名前がかぶっているなど、
起こり得ることは全て起こるのが前提です。
>>507 > 例えば、メソッドの名前変更。同じSignatureで意味の異なるメソッドが
> 存在する状態になると多態性を生かした既存のメソッドの再利用ができなくなる。
そうならないように、どうするの?
メソッド作るたびに、同じ名前にならないように全部チェックするの?
将来使うライブラリで、名前が被らないようにするには
どうすればいいの?
大変だね。名前がかぶっても問題ない言語もあるのに。
なんかさ、危険な道だから 徐行して通りました。 だから安全です。 みたいな事言ってる奴がいるなw
リファクタリング出来てない状態にならないように、リファクタリングして常に管理しておくつってんのに 既に崩壊してる状態とかなにいってんの? あと、他人が同じプロジェクトで開発してるなら、常にリファクタリングさせるし、 他人がまったく別の組織ならそのソースには手を付けないわ。その場合は、 その他人とこっちの管理下のソースのメソッドが仕様が異なるのに名前が同じにならないよう リファクタリングを行なっておくがね。
その「常に管理する」手間が 動的言語だと大変なんだよね。 名前がかぶってもわからないぐらいだし。
>>510 Gtagsとかそれ関連のツールつかっとけばいいよ。
そういうツールつかうなってなら、静的型言語もツール使わず
リファクタリングするのかいって話になるけど。
>将来使うライブラリで、名前が被らないようにするには
>どうすればいいの?
何が言いたいのか判らん
Refactoring Browserだってあるしなぁw
>>513 セレクターの入力補完とか使えば簡単じゃん
新規にライブラリーを追加する場合・・・ライブラリーを追加して外部のセレクターを書こうとした際、
入力補完にプロジェクト内のセレクターの名前が出てきたら
即リファクタリング
今使っているライブラリーと新規に ・・・入力補完でセレクター名が出てくる、仕様が同じなら同じメソッド名を使い
追加したメソッド名が重複しそうな場合 異なるなら、まだ未使用の別の名前を付ける。
517 :
デフォルトの名無しさん :2013/02/22(金) 23:17:29.46
ちょっとしたプログラムなら、grepで検索して、目で見て新しいメソッド名に書き直していけば、それでいいんだよ。 そうじゃないプログラムの時はどうしようもない。
あれぇ静かになったな連投規制にでも引っかかったか?
>>493 >たとえばその方法で Integer>>#factorial をメモワイズしたい場合はどういうふうにするの?
| value integer result |
interger := 3.
value := Memoizer selectWith: integer selectSelectors: #(#factorial:)
iresult := value factorial:2.
こんな感じ。今回のやり方だとobject生成の際にMemoizerのobjectでIntergerのobjectを明示的に包んでいるが、
Memoizerを継承してInterger風に振る舞うclassを作ればobject生成の際にMemoizerで包む処理を明示的に
記述する必要が無くなる。
ちなみにSmalltalkの機能を存分に活かすと、methodを入れ替える事ができるんで、Memoize用に既存の
methodをwrapしてclassに再代入し直すようなclassを用意すれば更に少ない記述量でMemoizeできるようになる。
ただ、そっちの実装は長くなるんでココに書く気力はない。
>>513 > 名前がかぶってもわからないぐらいだし。
それは動的型言語のせいじゃない。
おまえがツールの使い方を知らないだけ。
アウストラロピテクスからやり直せ。
>>506 >data.get()とかかていても、
>あー、dataは○型だね。○型のはインターフェースAを使ってるね。
>インターフェースのAを変えたってことは、この箇所のdataのget()も
>書き換えないといけないねって
>高度な推論が可能なのに!
…そうか、そんな簡単な作業すら静的厨には「高度な推論」なのか…
「がんばれ」
作業? ひょっとして、人間がやるとでも思ってるのか? (w
523 :
デフォルトの名無しさん :2013/02/23(土) 09:40:27.19
>>522 え?そもそも
>>506 に書いてあることは
「推論」と呼ぶに値しないほど簡単な「作業」に過ぎない
と指摘されていることも理解できないの?
もちろん、「作業」を人間がやる必要ないよねw
>>523 >「推論」と呼ぶに値しないほど簡単な「作業」に過ぎない
静的型付け言語ならね。
で、動的ならどうするの?
と指摘されていることも理解できないの?
> もちろん、「作業」を人間がやる必要ないよねw
そうだよ、全て IDE なりがやってくれるから。
静的型付け言語ならね。
動的言語なら 基底クラスのメソッドを変える場合 1.変えたいメソッド名でgrepする 2.そのメソッドが属するオブジェクトを見つける 3.そのオブジェクトが基底クラスもしくはそのサブクラスであればメソッドを書き換える。 オブジェクトの型はコード見てもわからないので、newされた場所まで遡る 4.この作業をgrepで見つかった全て行で行う。 という作業をやる。間違っている所ある?
基底クラスって考え方の時点でダックタイピング理解できてないよね アホには別のプログラミングパラダイムがある事が理解できないんだね
理解出来てないから、関係があることすら分からない
529 :
デフォルトの名無しさん :2013/02/23(土) 12:27:16.29
リファクタリングしやすいのは静的型付言語って、当然の話だろ。屁理屈こねても仕方ないじゃん。
>>525 その方法じゃ、テストができないからだめだね。
テストコードっていうのは、リファクタリング前後で
全く同じ物を使わないと意味が無い。
だからメソッドを変えたいとして
それが違う名前のメソッドになるとしたら
A.新しいメソッドを作る
B.古いメソッドから新しいメソッドに処理を移譲させる
C.テストを実行する
D.テストコード以外のgrepで見つかったメソッドの変更をすべて行う
>>525 の1〜4の内容
E.テストコード以外のメソッドの変更が終わったら、次はテストコードも同様にメソッドの変更を行う
F.全て終わったら古いメソッドを削除する
という工程が更に必要になる。
そう動的型付け言語ならね。
ダックタイピングがあるから 動的型付け言語はリファクタリングが 難しくなっている。
メッセージとメソッドの違いすら理解できない低能なんだね
533 :
デフォルトの名無しさん :2013/02/23(土) 12:45:05.12
grepで引っ掛かるならいいけど、getData()とかだと終わってる。 引数変更したくても出来ないから、どんどん増えて行ったり。
ダックタイピングがあって 基底クラスというものがない 言語ってあったっけ?
>>533 増える分には問題無いだろ
grepで引っかかったものを
一つ一つ、目視で判断していけばいい。
>>532 今は”メッセージ"がない言語の話をしています。
言い換えるとRuby、PHP、Perl、Pythonなどです。
だって、よく使われてる言語で話さないと机上の空論になるからね。
537 :
デフォルトの名無しさん :2013/02/23(土) 12:54:35.57
引数ドンドン増えて行ったらキツイだろ。 メソッドオーバーロード出来ないのもキツイな。
>>525 そもそも何で基底クラスのメソッド名変えるんだっけ?
あと、別に基底クラスの派生云々関係なく全部のメソッドと
メッセージ送信変更してしまえばええんちゃうん。
メッセージの要件が、クラスごとに異なる状態ってマズイだろ。
> そもそも何で基底クラスのメソッド名変えるんだっけ? 適切な名前じゃないことが、後で明らかになったから。
メッセージに関しては、 Ruby、PHP、Perl、Pythonの用語に 変更して言ってください。 Smalltalkの話は禁止します。 (あれは他の言事は違う独立した世界だから)
PythonとかRubyとかメッセージ転送できるので嫌です
Objective-Cもメッセージ使えるべ
>>525 > という作業をやる。間違っている所ある?
間違ってるところは無い。
想像通り面倒な「作業」頑張って下さい、としか言いようが無い。
メッセージが使える言語==メッセージを送信先のオブジェクトで処理せず他のオブジェクトで自動処理できる言語
>>540 なんで適切な名前じゃないことが後で明らかになったの?
>>546 最初っから正しい道を選べるわけがないだろ?
最初から最後までずっと間違わないでプログラミングできるとでも?
548 :
デフォルトの名無しさん :2013/02/23(土) 13:16:35.99
初めから完璧な設計出来るプログラマーの使用が許される言語。
>>541 ・Python
message = MessageCapture.selector( arg1, arg2, arg3 )
message.sendTo( target )
・Ruby
message = MessageCapture.selector( arg1, arg2, arg3 )
message.sendTo( target )
・Smalltak( Squeak, Pharo )
| capture message |
capture := MessageCapture new.
message := capture selectorWith: arg1 With:arg2 With arg3.
message.sendTo: target.
・Objective-C
NSInvocation *message;
message := [MessageCapture selectorWith: arg1 With:arg2 With arg3];
[message.sendTo: target ];
>>549 具体例って何の?
面倒くさいからtypoでいい?
無いとはいえないよなぁ
typoなら一括置換でいいよね
>>550 一般化すると
obj = Factory.create( arg1, arg2, arg3 )
obj.foo( arg )
っていうこと?
>>552 だめだよ。すでにあるメソッド名にtypoしたから。
>>553 違う。
・Ruby
message = MessageCapture.selector( arg1, arg2, arg3 )
message.sendTo( target )
例えば、上記の例からmessageの抽出を外すと
tareget.selector( arg1, arg2, arg3 )
になる。
>>550 の例は、メッセージ送信をMessageCaptureによって遅延している。
>>554 統合開発環境とかエディターの入力支援とかリファクタリングツールで気づくだろ
LL厨の言い分って理想論というか性善説というか 腐れ左翼の言い分に近いよなあ。 そりゃ世の中の人間全てがお前みたいな考え方してれば 世の中もちゃんと回るかもしれないけど、 そうでない人間が1人いるだけでうまくいかないのは明らか、 ということに気づいていない点が。
別に自分の周りが上手く行ってるならなんら問題はないがな CやらアセンブリみたいなLLの世界は大変なんだな
物を投げたら下に落ちる。素潜りして1時間も沈めば死ぬ。 もしかしたら、ある日を境に物を投げたらそのまま止まる日が来るかもしれない もしかしたら、その人は特別な訓練をしていて死なないかもしれない。 そんな特別な状況なんて重視する必要なんて無い。 他のプロジェクトがどんなに無様な状況に陥っていようと、 自分が関わるプロジェクトで同じ状況に巻き込まれなければそれで十分。
>>541 メッセージの概念を覚えておくと便利だぞ。C++やJavaみたいなメンバー関数型の言語じゃ
考えられないような事が色々出来る。オブジェクトに送られるメッセージを全て無視したり、
必要なメッセージだけを捕まえて他を無視。継承代わりにメッセージ転送を使うことで、
基底クラスを実行時に入れ替え。ネットワークやプロセス越しにメッセージ送信
ファイルにメッセージ保存して再生等など。
562 :
デフォルトの名無しさん :2013/02/23(土) 14:49:18.20
>>524 Refactoring Browserでポチっとな、で終わりだけど何か?
>>538 その程度の「作業」も一瞬で終わらないほど遅いマシン使ってるの?
え?まさか人間がやると思ってたの?バカ?
>>562 では、知っている言語とツール名を
”すべて” 教えてください。
Smalltalk用以外の物は無いと思ってますんで。
>>564 クレクレする前に、お前が知ってる言語とツール名を
「すべて」挙げろよww
さあ、今すぐ。
静的厨って、ツールはもらうものだと思ってるんだな。 プログラマなら普通自分用のリファクタリグツールは自分で作るだろ…
>>565 Eclipse、Visual Studio、NetBeans
次はお前の版だね。
>>564 Vim系ならGtags系と補完系を組みあわせるとTIBOに載るような言語は対応できるぞ
emacsでもその手のスクリプト有ったろ
>>568 使ってみたけど、制度低かった。
一つのファイルでしか出来なかったり
無関係のものを書き換えたら、
書き換えるべきものを書き換えられなかったり。
だから、補完系とか曖昧な言葉ではなく
具体的な名前でいってください。
てか、メンバー関数型の言語はリファクタリングが面倒だよな。 リファクタリング箇所が膨大になりやすい。 メッセージ&メソッド系はそこまで肥大しないのに。
あと、ここでいってるのは、 (人間が)一箇所だけ名前変更 → (コンピュータが)関連する箇所全て変換 してくれるレベルのもので、 候補を表示するだけで、一箇所一箇所 人間がコード読んで判断するようなものは除外です。
>>570 嘘をつけ。実際使ってたならタグ生成したソースファイル全部に対して補完や修正できたのを見たはずだ。
vimやemacsの補完って 単語ベースだから 無関係のものまで表示するんだよな。
575 :
565 :2013/02/23(土) 15:05:07.79
俺がコード書いたことがある言語は BASIC, FORTRAN, PASCAL, Ada, Modula-2, Modula-3, i8080アセンブリ, x86アセンブリ, K&R C, ANSI-C, C++, Objective-C, Common LISP, elisp, SML, OCaml, Haskell, Clean, Prolog, Smalltalk, R, Python, Ruby, Perl, PHP, Java, Scala, JavaScript ぐらいか。 環境は、それこそedlinやviからemacs, eclipse, 独自IDEまで色々。 全部挙げろと言われてもな。 静的型付、動的型付、型無し、いろいろ使ったけど、 動的型付はリファクタリングしやすいなんてことはないな。
>>572 じゃEclipseの置き換えもダメじゃね。
同じ意味で同じ継承ツリーに異なる関数がある場合は目視になる。
そうでなくとも、引数を増やす場合は全て手動になる。そもそも引数変わっとるからな。
>>574 Omni Compleate系だと単語単位じゃない。Omni補完って知らんのか?
>>575 お前日本語読めないのか?
Refactoring Browserの話だろw
まともな(
>>572 レベルの)Refactoring Browserが
ある言語と、そのリファクタリングツール名を聞いてるんだよ。
なんかわざとボケて話そらそうとしてる気がする。
もう無理だよ。一旦答えたんだから
最後まで答えてね。
579 :
565 :2013/02/23(土) 15:08:00.78
動的型付だろうが静的型付だろうが、リファクタリングし易さに大差ない。 静的型付のほうがリファクタリングしやすいと思うのは、動的型付を使いこなせてないから。 逆も然り。
Omni系プラグインと置換系プラグインそれから
>>516 の手順踏んでりゃ
困ることはねぇよ
>>576 人の話ちゃんときこうよ
>>572 は名前変換程度の簡単な作業の話
引数の追加の場合は、一箇所引数を追加したら
それに関する変更の必要がある場所全てを
列挙してくれる機能がほしいね。
これはリファクタリングブラウザじゃなくて
コンパイラの機能でできること。
動的型付け言語では無理だけどさ。
>>579 ここまでの話を聞くと
大差あるようにしか見えないよ
動的型付け言語でも頑張れば大丈夫!って結論だから
あぁ、頑張らないと無理なのかって。
583 :
565 :2013/02/23(土) 15:11:24.73
>>578 あのさあ、君のプログラマなら、
開発環境の機能を使うだけで解ったようなこと言ってるんじゃないよ。
標準のリファクタリング機能だけ使っているエンドユーザーのくせに
言語機能とリファクタリングしやすさの何がわかるというんだい?
>>572 はい、Tom。基底クラスに追加したメンバーが派生したクラスのメンバーと
重複していて、メンバー同士の仕様が異なるか同じかわからない状態で
自動修正できるのですか?
585 :
565 :2013/02/23(土) 15:12:13.35
>>582 頑張らなくても、普通にできることだけど?
標準機能じゃないと使えないの?そんなんでプログラマ名乗ってるの?バカなの?
名前修正なんて行わなきゃならない理由が、メンバー関数型に比べ、メッセージ&メソッド型は少ない
名前が同じなのにメソッド毎に意味が違うってバカな状況が作りづらいからな
>>572 に書いてあることなら、動的型のほうが楽だな。
静的型の場合、修正候補を型により区別しなきゃならないが、
動的型の場合は区別する必要なく全部修正すればいい。
全部修正されちゃ困る事情があるのなら、
同じ基準を適用すれば静的型でも自動的に変更されては困ることになる。
このスレを読んでわかることは、 動的型を攻撃しているレスを書いているのは静的型しか使った経験がなく、 動的型を擁護しているレスを書いているのは静的型も使った経験がある ということだな。
>>589 > 動的型の場合は区別する必要なく全部修正すればいい。
その結果、バグが発生するわけだがw
>>589 > 同じ基準を適用すれば静的型でも自動的に変更されては困ることになる。
静的型なら、ちゃんと「エラー」が発生してくれるから
バグにはならない。
「エラー」を直した後、修正すれば良い。
そしてエラーを直す作業も簡単。
名前を変える程度だから、自動でできる。
つうか静的型付動的型付の問題じゃねぇよな C++: template<class type> void Alpha(type object) { object.Member(); } Go 及びいくつかの言語の拡張( gccとか ): func Alpha( object interface{ Member() } ) { object.Member(); }
結論 動的型はリファクタリングに向いてない、と言ってるアホは 動的型をまともに使ったこともなければ 静的型すらIDE標準機能程度しか使ったことない
595 :
デフォルトの名無しさん :2013/02/23(土) 15:22:07.56
IDEがやってくれる仕事を、人間が頑張ってやる。
>>591 全部修正したらバグは発生しないよ。取りこぼすとバグが発生するかもな。
バカ?
>>591 なんで同じ仕様のメソッドが名前変えただけでバグを発生させるだけなんですかねぇ(迫真)
599 :
565 :2013/02/23(土) 15:23:32.94
>>567 で、肝心の「言語」は?
さあ、さっさと答えろよ。
600 :
デフォルトの名無しさん :2013/02/23(土) 15:24:14.77
Vimの補完とVSとかEclipseの補完じゃ比較にならんだろ。 まさかIDE使ったことないのか?
まさかvim拡張したことないの?
Vimが難しすぎ挫折したの?Vimはスクリプトの追加でメンバーの補完ができるんだよ。 今まで代表的なものにGtags系やtags系があったけど、最近はclangにツリーを生成させるってのもある。
>>593 動的型か静的型かの話と関数あるいはメソッドのディスパッチの話を
混ぜるから話がかみ合ってないよね
てか、問題になってた内容って補完はあんま関係ないよね。 Eclipseでもアウトなんだから。
>>598 > なんで同じ仕様のメソッドが名前変えただけでバグを発生させるだけなんですかねぇ(迫真)
同じ仕様であるという保証をする方法がないからでは?
多人数で作っていれば、たまたまメソッド名がかぶることがある。
別の人が作った、Aというライブラリと、Bというライブラリでかぶること
そして、言語にそれを検出する方法がなければ、
”気づかすに”そのまま使ってしまうこともある。
これは、「人間が気をつける」という仕組みでは
どうしようもないことだよ。
さあ、567先生が神技術で操る言語が何か、注目を集めています!!!
ここ見てると静的型付言語擁護してる奴だけが知識に乏しいよな・・・
>>599 言語は肝心じゃねーよw
質問はリファクタリングツールの名前で
それをお前は答えられてないじゃん。
逃げんのかよw
IQが10違うと話が咬み合わないとか、井の中の蛙とかそんなもんだろ。
メソッド名が同じでも、仕様まで同じとは限らないからなぁ。 これは動的型付け言語でも同じ話で。
>>605 だーかーらー、
Aで定義しているxというメソッドもBで定義しているxというメソッドも
両方ともyに置き換えてもバグにならないの。
別の言い方をすれば、AのxもBのxも両方ともyに置き換える操作が、
静的型での置き換え操作と同じセマンティクスになるの。
メソッド名が同じなら、仕様も同じにしないといけないんだよ! ↓ あー、わかったわかった、メソッド名が同じなら仕様も同じね。じゃあ、それをどうやって保証するの? ↓ 人間がおなじになるように頑張るんだよ! ↓ メソッド名が同じでも、仕様が違うもの扱えるように型やインターフェース型で区別すればよくね? そして、コンピュータがそれを理解できるの。 そうすれば、様々な開発サポート機能が搭載できるよ。 ↓ なくても人間が頑張ればいいだろ!
613 :
565 :2013/02/23(土) 15:36:25.26
>>608 俺は環境もいくつか答えたが?
おまえは言語を1つも答えていないな。
さあ、答えろ。
>>610 動的静的に関わらず、仕様が違う( 入出力に互換性がない )なら別の名前になるようにせにゃならんだろうけどな。
C++でテンプレート関数使うときに困るし、テンプレート関数に仕様を合わせてないと、
テンプレート関数を再利用できない。
615 :
デフォルトの名無しさん :2013/02/23(土) 15:37:47.55
ま、天才プログラマーで機械を超える高速で手を動かせる人は動的でもいいかもね。
>>611 > Aで定義しているxというメソッドもBで定義しているxというメソッドも
> 両方ともyに置き換えてもバグにならないの。
Aで定義しているxというメソッド(XMLファイルへの書き出し)も
Bで定義しているxというメソッド(CSVファイルへの書き出し)も
両方ともy(saveAsXML)に置き換えてもバグにならないの。
あぁ、バグにはならないな。
Bで定義しているCSVファイルへの書き出しが、saveAsXMLになるだけだからな。
>>612 へー、君にはここでの議論がそう解釈しているんだ?
悪いこといわんから、勉強して出直してきな。
>>612 >人間がおなじになるように頑張るんだよ!
↓
>メソッド名が同じでも、仕様が違うもの扱えるように型やインターフェース型で区別すればよくね?
>そして、コンピュータがそれを理解できるの。
>そうすれば、様々な開発サポート機能が搭載できるよ。
↓
>なくても人間が頑張ればいいだろ!
だから、ここVimや統合開発環境の機能で自動化できるって書いてんじゃん。
不都合は目に入らないのか?民主党かよ。
>>616 おまえはどうしようもないバカだな。
具体的に、saveAsXMLにする前のxの名前を書いてみろよ。
自分が言ってることがどれだけマヌケかよくわかるから。
Aで定義しているsave()というメソッド(XMLファイルへの書き出し)がありました Bで定義しているsave()というメソッド(CSVファイルへの書き出し)がありました。 あるときAにXML形式ではなく、HTML形式への出力が必要になりました。 Aで定義しているsave()ではどちらへの書き出しかわかりません。 それで、既存のsave()をsaveAsXML()に名前変更することに決めました。 そこでsave()を全部置換すると、なんと Bで定義しているsave()というメソッド(CSVファイルへの書き出し)まで saveAsXMLに書き換わってしまいました。 さあ、困りましたね。
いつまで初心者のお勉強につきあってあげるの?
>>618 自動化出来ねーよ。
同じ単語を、全部変えることしかできないから。
それじゃ問題大有りなんだよね。
ちゃんとコンテキストを読み取って
書き換えるべきところだけ書き換えないと。
>>620 バカだなあ。
そういう時には、「バカな静的厨がAとBを使って書いているC」を出さなきゃ意味ないじゃないかw
>>623 じゃあ、お前がそれを出して反論しろよ。このチキンが。
>>622 Omini系のスクリプト入れりゃコンテキスト読み取るつってんだろタコ。
>>625 型がないとコンテキスト読み取れねーよ。
func foo(obj) {
objは何型だよ!?
}
>>620 には「モジュール」という概念がないらしい…かわいそうな人だ…
628 :
デフォルトの名無しさん :2013/02/23(土) 15:46:14.48
動的型付には動的型付のメリットがあるんで、そのメリット生かせる場所で使えばいい。 動的型付のスクリプト言語なら、IDEで環境整えるよりも、Vimでさっさと書き始めた方がいいんじゃない。
今から、
>>627 さんが、「モジュール」を例に
ちゃんと解説してくれます。
もしくは逃げます。
>>620 OO的にゃXMLだろうがHTMLだろうがsaveであるべきだろ
セレクターに出力形式なんて紐付けんなよ
>>624 >6
反論もなにも、状況設定として完結してないっつってんだよカス。
AとBは別人が書いてるんだろ?
おまえは何を書いてるんだよ。それを書かなきゃ意味ないっての。
ここまで親切に教えてやってもまだ理解できないのか?
>>626 C++:
template<class type> void Alpha(type object)
{
object.Member();
}
Go 及びいくつかの言語の拡張( gccとか ):
func Alpha( object interface{ Member() } ) {
object.Member();
}
これとおんなじ問題だろ
633 :
デフォルトの名無しさん :2013/02/23(土) 15:48:26.58
スクリプト言語向けにもインテリセンスみたいなの実装してるIDEなくはないけど、結局まともに動かなくて、余計に混乱するからな。 メソッドの実装とコメント情報が合ってないとか。
モジュールがある言語なら、Aからimportしてるとこだけピンポイントすればいいな。 つまんね。
>>632 それはぜんぜん違うぞw
テンプレートはもともと”型を考慮しなくていい”ロジックを
まとめたものであるから、テンプレートがOKでも
テンプレートじゃないものはNGなんだ。
デグレする方向にリファクタリングツールを使って、 「こんなこと動的型付言語だったら出来ないだろエッヘン(ドやぁ」か リファクタリングツールがかわいそう
>>636 ダックタイプってのは全て
>”型を考慮しなくていい”ロジックをまとめたものであるから
だぞ
>>636 ランダムイテレータ―しか受け付けないテンプレートに
単方向イテレータ―入れたらアウトだぞ。
>>638 全てが、型を考慮しなくていいロジックじゃねーぞ?
たとえば、
foo(obj) {
obj.bar()
}
というコードは、bar()という一つのメソッドを持った
インターフェースを持っている方で無くてはならない。
>>640 ?
template<class type> void Alpha(type object)
{
object.Bar();
}
>>641 その場合、objectはBarを持っていないと
そのテンプレートを適用したクラスを作ると
コンパイルエラーになるね。
643 :
デフォルトの名無しさん :2013/02/23(土) 15:58:44.72
だいたいこの手の机上の空論は、本人がどんなに優秀でも、他人が書いたプログラムを読め、機能追加しろって言われた瞬間に崩壊する。
テンプレートってC言語のマクロみたいなものだからな テンプレートが展開された後で 改めて型チェックがされる。
>>642 何の話してたか覚えてないの?
ここでBarを変えたら、どっちもコンパイル時ないし実行時にエラーが起きる。
>>645 え? メソッドが同じでも意味が違うものがあるから、
単純に同じ名前だからって置換したらだめだよって話だろ?
>>647 まずそうい状態にしちゃいかんよな。テンプレート使うときに困るし。
例えばあるライブラリに、childrenというメソッドがあるけど これは何の処理をするのかってわからないからなぁ。
>>648 いかんよなぁ。じゃなくてなってしまうんだよ。
作る人は一人じゃないんだから。
他人が自分の知らないところで作ってしまうことがある。
わからないなら、自分の管理下はそのメソッドと同じ名前を使わないようにすりゃいいんだろ。 vimとかemacsとかのスクリプトつかって。
>>650 複数人で作ったんならマージするときに直せば済むじゃん。
コミュ症で周りと会話できないの?
>>650 Javaに限った話になるが、基底クラスに勝手に派生と同じ関数定義されてたらどうすんの?
いままで散々出てるがそれと同じ話なんだけどな。
655 :
デフォルトの名無しさん :2013/02/23(土) 16:14:25.82
>>558 > LL厨の言い分って理想論というか性善説というか
> 腐れ左翼の言い分に近いよなあ。
>
> そりゃ世の中の人間全てがお前みたいな考え方してれば
> 世の中もちゃんと回るかもしれないけど、
> そうでない人間が1人いるだけでうまくいかないのは明らか、
> ということに気づいていない点が。
左翼って表現上手いな。確かにそうだな。
で、結局最後まで自分が知ってる言語のリストを晒さなかった静的厨は 性悪説ということでオッケーでしょうか?
>>654 > Javaに限った話になるが、基底クラスに勝手に派生と同じ関数定義されてたらどうすんの?
基底クラスにはないメソッドを派生クラスに定義するとき、
つまりオーバーライドしないときは
派生クラスに@Overrideアノテーションは当然不要。
基底クラスに勝手にメソッドが追加されたら
@Overrideが無いという警告が出るからすぐに認知できる。
動的型付け言語みたいに”気づかなかった"は起こらない。
>>656 誰か言語のリストを要求したっけ?
リファクタリングブラウザの名前を要求したのに
それを出さなかった話しなら知ってるが。
リファクタリングブラウザの名前は出さなかったんじゃない。 出せなかったんだ。
>>657 継承ならvimやemacsとかのプラグインで警告出せるよ
>>657 なるほどね。動的言語にも@Overrideみたいなのが欲しいところだけど、
動的言語故に、実行時にメソッドが追加されたり削除されたり
することがあるから、静的にコンパイルチェックすることは不可能だろうね。
PythonならPySonarみたいな解析ツール使うてもあるで
>>662 pythonならpython.vimとか
>>658 564 2 名前: デフォルトの名無しさん Mail: sage 投稿日: 2013/02/23(土) 14:52:07.25
>>562 では、知っている言語とツール名を
”すべて” 教えてください。
Smalltalk用以外の物は無いと思ってますんで。
565 7 名前: デフォルトの名無しさん Mail: age 投稿日: 2013/02/23(土) 14:53:43.72
>>564 クレクレする前に、お前が知ってる言語とツール名を
「すべて」挙げろよww
さあ、今すぐ。
>>661 たぶんpythonのデコレータでできるよ。
def overrides(klass):
def overriding_method(base_method):
assert(base_method.__name__ in dir(klass))
return base_method
return overriding_method
こんな感じ。
>>665 へー、なんでそこで要求されている
リファクタリングブラウザ名はでなかったの?
おかしいよね?
>>667 > 警告でたあとじゃ遅いだろうに
え? コンパイル時の警告じゃ遅い? どういう理屈で?
動的言語だと、警告は 実行された時に出るんだぜ。 遅すぎるだろw
>>668 vimやemacsでもリファクタリングできるじゃん、というのが答えだったのが読めないわけ?
ふーん…
>>671 できるけど、時間がかかって大変だって話でしょ?
>>670 666のコードだと、いつ警告が出るかわかるか?ニヤニヤ
>>666 5行も必要なんですか!?
あらかじめそれやってないと
警告でないってことですよね?
>>672 どうしてvimやemacsでは時間がかかると思うわけ?
>>669 マージの際に警告でたんなら意味がない
マージ以前ならもともと関係ない
静的型厨がPython読めないことが確定したな。
>>674
>>676 それは?屁理屈?
実行前に警告出てれば遅くないよね?
実行前の警告が遅い理由を聞いてるんだけど?
>>679 実行前に警告というか問題点をツールで見つけ出すんならこのスレで散々でた方法で対応できる。
問題は他人がいらんことしたソースとマージするときの話だったろ。
>>631 ,642
C++ の template はまさに「そこがわかりづらい!」
ってことで Concept の導入が検討されてただろ。
議論不足ということで先送りになったが。
>>678 具体的に、人間がどれをやると思っているわけ?
どうして全部ツールがやってくれると思わないわけ?
vimやemacsを標準のまま使うという制約がどこかから湧いて出てきたわけ?
>>674 ねえ、もしかして、デコレータって言葉がわからないの?
だから
>>666 のコードを毎回書くとか勘違いしちゃったの?
いつになったら静的型厨の言語歴リストを晒すの?
静的型付動的型付は置いといて、 メッセージングの概念が無い言語、 委譲支援機能が無い言語は、継承から 委譲への変更が圧倒的にメンドイ。 例え、委譲だけする関数を自動生成させたとしても、 元のクラスに関数が増える度に追加しなきゃならんからかったるすぎる
とりあえず、一人で必死にがんばってる人はPythonを読めないことが確定した。 どうやらemacsもvimも使ったことないようだ。 彼は一体何を根拠に動的型はリファクタリングできないと思い込んでいるのだろう?
>>568 君が使える言語のリスト、まだ?
このままじゃ君はただのバカだよ?
>>658 君が使える言語のリスト、まだ?
このままじゃ君はただのバカだよ?
>>682 なぜそう思うかは簡単。
お前が一向に、ツールの名前を言わんからだ。
リファクタリングのツールの名前を 言わないのはなんでなんだろうね。
>>688 python.vimとかPySonarとかGtagsとかは具体的なツールじゃないんですかねぇ
Javaみたいな言語でどうやったら継承から委譲へのリファクタリングが楽になるんですかねぇ〜
>>691 ん? もしかしてお前、リファクタリングの意味がわかってない?
Java以外で継承から委譲へのリファクタリングをやってみてよ。
JavaやC#は委譲先のクラスにメンバーが増えたら委譲先クラス全てに逐次メンバー追加 20個あったら20個追加。リファクタリングツール使ってもかったるいわ〜 委譲を自動化できる言語なら委譲先クラス一個にメンバー追加するだけで済むんだけどなぁー C++ですらテンプレート使えばある程度対応できるのになぁ〜
>>688 既に一杯出ているのに?
いつになったら言語リストを晒すんだ?
単にバカなだけでなく、卑劣な人?
class Derived < Base end から class Derived def initialize( guest ) @base = guest #あるいは@base = Base.new end def method_missing( selector, *args ) @base.send( selector, *args ) end end へ変更。委譲先メンバーが増えた所で委譲元には追加修正不要
>>691 > Javaみたいな言語でどうやったら継承から委譲へのリファクタリングが楽になるんですかねぇ〜
ステップ1 extends HogeとなってるクラスにHoge型の持ったプライベート変数を作る
public class Hage extends Hoge {
private Hoge hoge; ← 追加
略
}
ステップ2 右クリックメニューより「委譲メソッドの作成」を行う。
全てのメソッドであれば特に設定項目はない。OKを押すだけ。
これで委譲メソッドが何十個あろうと生成される。
ステップ3 extends Hogeを削除する
ステップ4 Hoge hogeをnewするコードを書く
委譲だけに以上!w
>>695 の欠点は、
委譲先が二つ以上あったらどうすんの?って所かな。
Smalltalkだと (A allSelectors reject: [ :s | B allSelectors includes: s]) do: [ :selector | B compile: selector, String cr, '^ a ', selector classified: 'delegation' notifying: nil ] の1行でAにはあるがBにはない全てのメソッドを委譲するメソッドを自動生成できる。 もちろん移譲先が複数あっても問題ない。
おっと、699のコードは単項メッセージの場合な。 キーワードメッセージありだともうちょい長くなる。 どのみち一行で済むけどね。
ところで、いつになったら静的厨の言語リストが出てくるのだろう。
自分から言語を全部挙げろと言っておきながら、卑怯だよね。
>>699 委譲先A、B両方に、同じメソッドがあったらどうすんの?
>>702 ツール名は? 中途半端に上げるのも卑怯
>>703 選べばいいんじゃね?Javaだって複数の移譲先があったら選択するんだろが。
>>704 ツール名は既に沢山挙っているが?
挙ってないと嘘ばかり言ってるのは君だけだよ。
さあ、君が使う言語のリストを挙げなさい。
>>706 リファクタリングツールだよ。
一番使われている動的言語であるRubyに
限っては一個も出てないし。
>>705 でもそれだと、気づかないってことがあるだろう?
>>699 裏切って悪いけど、俺ならこれで済ませるわ
doesNotUnderstand: aMessage
aMessage sendTo: target.
>>703 Javaでも同じだろ。ただ、移譲先が1つの場合は自動移譲出来る方がリファクタリング回数が少なくて楽。
そもそも、単一継承してる言語で、継承を移譲に変えると移譲先が2個に増えるなんて無いから。
リファクタリングについて技術的な議論をしたければ、すればいい。
動的型言語をまともに使ったこともないのに
動的型言語ではリファクタリングできないなどと
デマを流すのはやめろ。
お前がバカであることを自ら晒すのは自由だが、
デマを信じて広めるバカが出るのが迷惑なんだよ。
せめて
>>666 ぐらい一目で読めるぐらいに勉強してから出直してこい。
>>707 リファクタリング用と書いてある専用ツールを使う必要はない。
ruby.vimなんてもんでも十分。
>>708 移譲先に共通するセレクタを列挙するコードでも貼ればいいか?
ものすごく簡単だが?
>>709 > そもそも、単一継承してる言語で、継承を移譲に変えると移譲先が2個に増えるなんて無いから。
すでに委譲していた → 継承をやめたから委譲先が2個になった
>>709 doesNotUnderstand:を使うとsendersやimplementorsにかからなくなる。
あと、実行時のオーバーヘッドも無視できん。
>>699 なら通常のメソッドと同様に扱える。
委譲したくないセレクタがあっても対処できる。
などなど、
>>699 にもメリットが多いぞ。
委譲って普通、一部だけ委譲したり 委譲する前に何かしらの処理を挟んだり するもんじゃねーの? 継承関係がない無関係のクラスに 同じメソッドをもたせる事例が 思いつかないんだが。
つ proxy pattern
継承は限定的にって流行りは終わったの?
718 :
デフォルトの名無しさん :2013/02/23(土) 20:51:44.66
リファクタリング出来ないってわけじゃなくて、リファクタリングするのが面倒で間違いやすいってことだろ。
Javaなんかだと、委譲だけでなくて 多くのコードをEclipseが生成してくれるけど、 そうやって自動生成に頼ってるおかげで どんどんコードが膨らんで可読性が落ちるんだよねー 可読性を高めるためのリファクタリングなのに、 冗長すぎて可読性がウンコって問題あると思うよ
720 :
デフォルトの名無しさん :2013/02/23(土) 21:10:18.35
それはJavaの言語仕様の問題だろ。
721 :
デフォルトの名無しさん :2013/02/23(土) 23:02:05.89
>>719 Eclipseが自動生成するコードってどんなもののことを言っている?
結局、Java厨は言語リストを晒さずに逃げました、と。
>>718
>>722 こんな時間まで粘着してたのか?
ストーカーかよ
>>718 ツールが自動的にやってくれるのに
どうして面倒で間違えやすいと思い込んじゃったの?
Javaしか書いたことないから?
Eclipseしか使ったことないから?
バカだから?
Java、C、C++、JavaScript、VB、C#、PHP、Perl、アセンブラ(x86) こんな所だな。
つまり、動的型での継承関連のリファクタリングについて どうこう言える経験はない、ということか。
なんでそう思ったの?
>>726 のリストには
動的型言語が一つも含まれてないからさ
お、おう
>>726 >Java、C、C++、JavaScript、VB、C#、PHP、Perl、アセンブラ(x86)
うち、動的型は
JavaScript、PHP、Perlだが、
どれも継承関係を中心としたプログラミングをする言語ではない。
え? あぁ、せやな。
>>718 これだけ先達が色々教えてくれているのに
すこしは学んだらどうだい?
>>729 みっともない自演はやめたほうがいいぞw
JavaScriptにいたっては 継承どころかクラスがない。
>>731 も自演かな?
あまりにも知識が少なすぎる。
これは面白い。 動的言語厨が、他の動的言語を 馬鹿にしだした。 仲間割れだ。どんどんやれ。
>>737 煽っても無駄だよ
このスレには少なくとも5人が書き込んでいるが
状況を理解できていないのは君一人だw
>>736 そうだね。
で、どの動的型言語で継承関係のリファクタリングをしたんだい?
具体的に言ってごらん?
途端にレベルが下がったな、 JavaScript、PHP、Perlでも 継承使うっていうの。 これらのフレームワークで 継承使ってないもの持ってきてみろって。 所詮、実践言語を知らない 机上の空論言語使いだったか。
ここでオプショナルな型付け言語の登場で世界は平和に。
>>740 具体的に、どんな継承関係のリファクタリングしたのか言ってみろってwww
言語が進化するってのを知らないのでしょうね。 古い知識で物を言っている。 まあ、Perlがオブジェクト指向に対応したのが1994年だし。 PHPがオブジェクト指向に対応したのが2000年、 トレイトに対応したのが2012年。 JavaScriptはプロトタイプベースというものを知らないだけ。 仕方ないよ。
>>742 PHPでメソッドが存在しない時、
__callが呼ばれるので、他のメソッドに
委譲しただけですよぉ?w
>>575 >BASIC, FORTRAN, PASCAL, Ada, Modula-2, Modula-3,
>i8080アセンブリ, x86アセンブリ, K&R C, ANSI-C, C++, Objective-C,
>Common LISP, elisp, SML, OCaml, Haskell, Clean, Prolog,
>Smalltalk, R, Python, Ruby, Perl, PHP, Java, Scala, JavaScript
なるほど、これが「机上の空論言語」か
ちなみに
>>731 から
>>575 に挙った「机上の空論言語」を取り除くと
C#しか残らないように見えるのは気のせいだよなw
確かに知識が古いようだな。 古い動的型のイメージで「リファクタリングできない」とか言っちゃってるのだろう。 仕方ないとはいえ、こういう人が偏見で都市伝説をつくっているんだろうな。
はっはっは。言語名を列挙するだけなら誰でもできるからなぁ。 > うち、動的型は > JavaScript、PHP、Perlだが、 > どれも継承関係を中心としたプログラミングをする言語ではない。 お前がアマチュアだってのは、このセリフから 明らかになったし。
PHPには継承機能はないんだが、 どうやって継承しろと?
JavaScript, PHP, Perlに継承がないなんて誰も言ってない気がするが? 相手の主張を歪曲して叩くのって、楽しい?
>>747 おまえはPHPで継承を「中心にした」プログラミングをしているのか!?
すげえぜw
>>749 え? じゃあなんて言った?
一つでもフレームワークの名前しってる?
JSでプロトタイプ委譲することはあるが、 それが開発の「中心」になることは、まずないな。 ましてや「継承を中心」となると…
>>750 好む好まない関係なく、
PHPの今の開発で普通に使われるフレームワーク
ZendFramework、CodeIgniter、CakePHP、Symfony
どれも継承を中心にしたプログラミングだよ?
>>752 最近はやりのBackbone.jsは
ModelやViewを継承したクラスを作るんだが?
>>751 「どれも継承関係を中心としたプログラミングをする言語ではない。」
という発言なら、
>>731 がしているな
まさか、これが「継承がない」に読める?バカ?
継承があって継承を使う。 なんで、それで継承関係を中心とした プログラミングにはならないって 思っちゃうわけ? 継承関係を中心としたプログラミングに ならない根拠はなんだよ?
俺が知らないから(ドン!) だろうなw 俺の常識では〜 以下本人の言い訳を御覧ください。
>>754 では、Backbone.jsを使ったコードについて
具体的な継承関係のリファクタリングを見せてもらおうか
> うち、動的型は > JavaScript、PHP、Perlだが、 > どれも継承関係を中心としたプログラミングをする言語ではない。 だって JavaScriptプログラマも、PHPプログラマも、Perlプログラマも その、くぷぷ。だってそんな技術力ないじゃない。くぷぷ あんなやつらに継承とか理解できないよ。くぷぷ。 これが理由じゃ不服かい?くぷぷ。 とか言ったら殺されるされるだろうなぁ。 オブラートに包んで言っても、ばれるよ。 下に見てるのは。
>>756 継承以外のウェイトが大きいからじゃね?普通に考えて。アホ?
>>758 継承から委譲にするために、
クラスに存在しないメソッドを
他のクラスから取り込みました。
クラスのメソッドを列挙する方法ですか?
for inでできますよ?
あ、きてたw
>>761 そうだよねー
動的型だからリファクタリングできないとか言うバカがいるらしいよ
アホだねー
つーか、 JavaScript、PHP、Perlで オブジェクト指向できないのは 世間の常識なわけで。 いい加減認めちゃいなよ。
>>764 リファクタリングに時間がかかるじゃなかったっけ?
>>766 そうなんだよねー
JSで委譲コード書くのは時間がかかって大変だよねー
あはは
768 :
デフォルトの名無しさん :2013/02/24(日) 08:28:35.96
javascriptとphpとperlをちょっとかじっただけで 動的OO言語でのリファクタリングについて熱く語り出す事案が 発生しました
>>715 高機能なconceptを低機能なobjectにemulationさせて実現させる際に頻繁に使用する。
委譲が自動で出来る場合は割と定石だから覚えとけ。
| simpleContext complexContext |
simpleContext := openGLDevice simpleContext. "委譲先のcontextを取得"
simpleContext lineTo: 10@10.
complexContext := ComplexContextForSimpleContext with: simpleContext. "委譲を行うobjectを生成"
complexContext lineTo: 10@10. "simpleContextと同じlineToを使用する"
complexContext drawRectangleFrom: 1@1 To: 10@10.
"ComplexContextForSimpleContextによって追加されたmethod。
lineToやらSimpleContextのconceptが備える最低限の操作を
使用して矩形描画を再現する"
complexContext := svgDevice complexContext. "SVG用のcontextを取得"
complexContext lineTo: 10@10.
complexContext drawRectangleFrom: 1@1 To: 10@10. "svgDeviceのdrawRectangleFrom:To:が直接実行される"
>>731 アセンブラ lol
アセンブリ開発したことありゃアセンブリっつうだろ
この不毛な煽り合いのなかにあえてレスするが 俺はゲーム業界だけどアセンブリって言う奴ほとんどいない
772 :
769 :2013/02/24(日) 08:59:52.76
× complexContext drawRectangleFrom: 1@1 To: 10@10. "svgDeviceのdrawRectangleFrom:To:が直接実行される" ○ complexContext drawRectangleFrom: 1@1 To: 10@10. "svgDeviceから取得したSVGContextのdrawRectangleFrom:To:が直接実行される"
ゲームクリエイター学科もゲーム業界だろ(迫真)
実際Assemblyを使う組織で働いてると、Assembly, Assemble, Assemblerは区別して話さないと混乱する。 ある種類のAssemblerが使えるのと、ある種類のAssemblyが使えるのじゃ全然違うからな x86のAssemblyが使えるったって、MSのAssemblerを使ってなのか、gasを使ってなのかじゃ話が大きく変わる
775 :
デフォルトの名無しさん :2013/02/24(日) 09:14:46.26
マシン語、アセンブラ むかしからいうんだよ
ハンドアセンブル
>>775 実際にドライバー開発とかしてた奴らは昔っから区別しとったよ
英語の意味を理解してるとアセンブリをアセンブラーと呼ぶのは気色悪い
>>780 それはロクに使ったこと無い奴がアセンブラ言語って言うだけだよ
門外漢がアセンブラ言語っていうから、アセンブラ言語って言い回しが無いわけじゃない。
そもそもアセンブラx86とかどのアセンブラだよ。 masmかgasか?msasmか?
wikipediaの脚注1 > IBMはSystem/360から2011年現在まで一貫してアセンブラ言語(Assembler Language)と呼んでいる。例:IBM High Level Assembler 天下のIBMやIPAがアセンブラ言語っていってんのに2chの底辺でどっちが正しいとか話しても虚しいだけだろw たぶん君等が糞みたいなレベルだから、こんな糞みたいなどうでもいいことが気になるんだよ
>>780 使ってるアセンブリが違いました
使ってるアセンブラが違いました
よく使う言葉ほど簡潔に
リファクタリングで論破されたからって、アセンブ{ラ|リ} で熱く語る奴って…
>>784 自分が糞だからといって、他人まで糞だと言うのは間違いだぞ。
790 :
デフォルトの名無しさん :2013/02/24(日) 17:12:29.05
JSもいわゆるベターJSは継承あるし型も静的に指定出来るよね。ある程度大きなプログラム書こうと思うとそうなる。
>>790 できるのとするのとではちがう
JavaScript、PHP、Perlは動的型だが
どれも継承関係を中心としたプログラミングをする言語ではない。
792 :
デフォルトの名無しさん :2013/02/24(日) 18:26:08.73
JSはともかく、PHPとPerlは普通に継承使うと思うけど。
>>791 > どれも継承関係を中心としたプログラミングをする言語ではない。
できない人の言い訳はいらないよ
731 名前:デフォルトの名無しさん[sage] 投稿日:2013/02/24(日) 07:03:00.27
>>726 >Java、C、C++、JavaScript、VB、C#、PHP、Perl、アセンブラ(x86)
うち、動的型は
JavaScript、PHP、Perlだが、
どれも継承関係を中心としたプログラミングをする言語ではない。
そうでちゅねー さんざん馬鹿晒した逆恨みのなりすまし、かっこ悪い
続きは「PHPとPerlこそが真のオブジェクト指向言語」とかいうスレ立ててそこでやれ
あんなに罵詈雑言あびせたら恨まれて当然。 もっと優しく教えてやれよ。
799 :
デフォルトの名無しさん :2013/02/24(日) 19:21:25.46
最近だとむしろJavaの方が継承使わないよね。何でもSpringでインジェクションでしょ。
DIで注入される個別の実装を開発するのに普通に継承は使うが。
801 :
デフォルトの名無しさん :2013/02/24(日) 19:43:57.93
どうだろう、出来るだけPOJOにしようというのが今のトレンドでしょう。 ま、意固地になって継承拒否する必要もないけど。
でも継承ってウンコだよね よろこんで使ってるの低能だけ
>>801 DIで注入されるDaoやサービスの類を実装するのに普通に継承は使う。
注入される側も実装の共有が出来る部分では普通に継承を使う。
DI使えば継承不要とかPOJOとかまるで謎。むしろDI使うことで個々の部品が小さく
なって独立性も高くなるので、実装の共有のための継承がし易くなった。
DIでインジェクションするのと継承は無関係の話だよ。 DIがやるのは、オブジェクトをnewする部分を 置き換えるもの。継承を置き換えるわけじゃない。 継承はオブジェクトの構造を表現したものだが DIはオブジェクトを誰がどうやって生成するかを表現したもの。 is-a関係にない構造(例 モデルがDBクラスを継承するとか)なのに なぜか継承しているものを委譲に変えるときに、 委譲先オブジェクトをインジェクションする。 その結果POJOになるって所から勘違いが広まってるんだと思う。
DIって静的型付けOOPLのゴミなところが良く出てて 大変微笑ましい
一体いつになったら、動的言語がDIの世界に 追いつくんだろうね。
動的言語の世界に追いつこうと足掻いてるのがDIなんだが 本当に分かってんのか?
DIは動的静的関係無いと思うのだけれどもな。
ただのStrategyパターンの一種に大騒ぎ
811 :
デフォルトの名無しさん :2013/02/24(日) 20:25:10.85
いや、多重継承やトレイトがJavaにあればここまでSpringは流行らなかったと思う。 既存のウェブフレームワーク使うなら、一切継承使わずにSpringだけでウェブアプリ書けちゃうと思うよ。 そういやPHPもアノテーションが導入されるんじゃなかったっけ。
812 :
デフォルトの名無しさん :2013/02/24(日) 20:26:19.03
あとDIと動的静的は明らかに無関係だと思う。
オブジェクト指向と同じでDIは考え方だよ オブジェクトが他のオブジェクトを利用するとき、 オブジェクトが直接newするのではなく、 他の誰かにnewしてもらうことで依存関係を減らす。 という考え方。
どうもオブジェクトの生成を外部にやってもらうという DIの本質がわかってない人がいるようだね。 DI(Depencancy Injection = 依存関係の注入)という 言葉の通りで、注入することが、一番の本質なのに。
815 :
デフォルトの名無しさん :2013/02/24(日) 20:37:56.15
依存関係を無くすために、依存関係を外部から注入することがDIの本質なわけで 多重継承やトレイトのように内部で注入することは依存関係ができてしまうので DIの目的をみたしていない。
>>815 うん、みんな最初はわからないものだよ。
コンストラクタをクロージャとして引き回せる言語使ってれば ただのStrategyパターン
>>811 多重継承やトレイトがあったところでそれが静的なのであればDIのメリットは殆ど再現出来ない。
クラス定義時にではなく実行時に動的に注入するから、注入するクラスを差し替えたり一つの
共有インスタンスを沢山の注入先に注入するといったメリットが出てくる。
つまり動的言語であれば多重継承やトレイトでDIのメリットは再現できるってことですね
DIは考え方で、それをどうやって実装するかの話でしょ? そりゃなんでも実装できるよ。 実装するための技術はなんでもいい。 実装されたDIに価値がある。
DIの考え方を理解してないものが 僕の考えるDIを語っても的外れになるだけってことが よく分かるな。
>>820 状態を持たないアルゴリズムの実装の注入や差し替えであれば多重継承云々でも出来るだろうね。
ただごくごく一般的な例として、例えば使い回ししたいデータベースハンドラを注入する場合、
多重継承やトレイトではどうやるのだろう。
最初にJavaでDIが出て来たときは 冗長なXMLで書いてドヤ顔したあげく XML地獄になっててワロタwww センス無い連中が実装技術作ると悲惨だなって
825 :
デフォルトの名無しさん :2013/02/24(日) 20:56:29.59
一応アノテーションでXML地獄からは遠ざかれるけど、Springとかに依存しておいてPlainでもOldでもないわな。 Javaみたいな単一継承の言語の場合、移譲に頼るしか仕方ないけど、やっぱトレイトやミックスイン使う方がスマートだと思うわ。
クラスのミックスインやトレイトはDIの代わりにならんと思う。 インスタンスを注入できないと意味が無い。
827 :
デフォルトの名無しさん :2013/02/24(日) 22:06:29.70
何の為にDI使ってるかによるだろう。AOPならトレイト使えば自然に実現できる。Javaにトレイトはないけど。
それはたまたまSpringその他のDIコンテナがAOP的な機能「も」実装しているだけの話であって SpringのAOPにしてもDIはしていないぞ。DIを使うこととDIコンテナを使うことは区別しろよ。 Beanの生成をSpringフレームワークが制御するという特質を上手く利用して、Bean生成時に プロキシクラスでラップしているだけでしょ。Beanを包みこそすれ何も注入はしていない。
>>825 > Springとかに依存しておいてPlainでもOldでもないわな。
君、わかってないよ。
Springを使ったとしても、Springに
依存することはないんだよ。
不思議でしょう?
DIコンテナ以外のフレームワークが、クラスに便利な機能を提供するのと違って
DIコンテナは依存関係を分離するためにクラス外から注入することに特化しているから。
厳密に言えば昔はDIするために@Autowiredとかアノテーションつけてしまうと Spring依存になってしまったけれども、今はDI用のアノテーションもJSR330で javax.injectとして標準化されたものが使えるから、アノテーションでDI定義 しても使うDIコンテナには非依存だね。 Mavenに何個かdependency追加してポチポチとアノテーションつければサクッと DI使える。別に身構える必要も何もないお気楽技術になって快適至極。
>>830 というか、そういうことでもなく、
Springを使えばSpringがなければシステムが動かないのは当たり前。
依存関係っていうのは、クラスが他のクラスの実装に依存してしまうこと。
インターフェースに依存するのは問題ないけれど、実装に依存すると
その実装を他に実装に(ソースコードを修正せずに)に置き換えれない。
だからクラスではインターフェースの利用は行うけど、
その実装はクラス内部では生成(new)しない(=外部で行う)というルールにしましょう
っていうのがDIという考え方。(そしてそれをやってくれるのがDIコンテナ)
DIを使うことを前提にしたクラスは、他のクラスに依存しないから
再利用や単体テストがしやすくなる。システム全体を動かすときはspringがいるけど
(システムってのは依存関係の組み合わせてできるから当然)
そのクラスを単体で使うときspringはいらない。
クラス生成部分の依存関係を取り除いたのがDI。
動的言語では、DIコンテナは言語仕様で簡単に実装できる事が多いが
だからといって、クラス外部でnewするというDIという構造になるかどうかは別問題。
自分でクラス内部でnewしないように、気をつけないといけない。
でそういうのをコーディングルールとして書くよりも
DIコンテナというフレームワークを使うことで、自然とコーディングルールになるほうが健全
だから動的言語でもDIコンテナは有用。
それは例えば「gotoは例外目的にだけ使いましょう」というコーディングルールを作るよりも
例外を作ったほうが意図が明確になるのと同じ事。
>>831 というか、そういうことでもなく、一段階下のレイヤーの話ね。
DIをするには何を何処に注入するかという情報をどこかに書く必要があるわけだけど、
それが昔はapplicationContext.xmlなどの外部XML、昨今はアノテーションが便利。
ところが設定XMLの仕様とか用意されたアノテーションはSpringといったDIコンテナの
実装の一部であるわけで。
特にアノテーションはSpringの実装で用意されたJavaアノテーションそのものだから、
ビルドにも実行にもSpringの実装を必要とする。DIのアノテーションを使う事で
コンポーネント間の依存性を簡単に疎にできる一方で、コンポーネントがどうしても
DIコンテナの実装に依存してしまうのが難だった。
別の言葉で言うと、コンポーネントの実装を差し替えるのが簡単な一方でDIコンテナ
の実装を差し替えることは簡単じゃなかった。特にアノテーション使うとDIコンテナ
への依存性がクラス定義に埋め込まれてしまうのでにっちもさっちもいかなくなる。
でも今はjavax.injectの@InjectアノテーションをつけておけばSpringでもGuiceでも
正しく注入される。DIに関してはDIコンテナへの依存をかなり減らして書けるように
なってきて良い時代だなぁと。
話についてこれない動的厨かわいそうw きっと動的言語最強だから こんな知識不要とか思ってるんだろうな。
だって、DIなんて動的言語なら簡単すぎるからな ていうか内部でnewしてたって後で入れ替える事すらできる まあメタクラスとか知らんだろうけどな
>>834 それ、カプセル化ぶち壊しってだけだぞw
function foo() {
var o = new Obj();
o.bar();
}
で、どうやって入れ替えるの?
DIごときにメタクラス持ち出す時点でDIを理解していないw
依存性の注入自体はリフレクションの類を使わなくともコンストラクタの引数やセッターを 介して出来るからリフレクションの類は必要ない。 ただ動的言語、というか実行時コンパイルの言語の場合設定ファイル自体が実行可能コードで ある場合も多く、その場合は他の設定と同様に注入も設定ファイルの中にDSL的な記法で直接 コーディング出来たりするので特にDIコンテナは必要が無い。 他方で事前コンパイルなJavaの場合、設定ファイルがJavaファイルということはまず無い。 なので注入はコードとして記述は出来ず、XML等で記述された情報を読んでリフレクションを 使って注入をしていく必要があるので、その辺の面倒くさい作業ががDIコンテナとして実装 されている、のだと思う。アノテーションも同様。 動的言語の世界にDIコンテナをあまり見かけないのは、動的静的云々よりも実行時コンパイル か否か、設定ファイル自体がコードであるか否かの違いではないかなと思う。
> 依存性の注入自体はリフレクションの類を使わなくともコンストラクタの引数やセッターを > 介して出来るからリフレクションの類は必要ない。 コンストラクタの引数やセッターを介してやると冗長になるんだよ Javaのようなウンコ言語の場合は
>>835 class T(type):
pass
class Obj(metaclass=T):
def bar(self):
print('bar')
def foo():
o = Obj()
o.bar()
foo() # => bar
class Foo():
def bar(self):
print('foo')
T.__call__ = lambda self, *args, **kwd: Foo()
foo() # => foo
普通にセッター使った方が簡潔で判りやすいことを実感させてくれる例ですどうもありがとうございました。
デコレータすら読めないアホ(
>>674 )が分かり易さを語ってもなー
普通にオブジェクトをセットするだけで済む簡単なお仕事なのに、なんでわざわざ リフレクションでロジックにホットパッチ当てるのに固執するのかよくわからんw ちなみに今時のDIコンテナは注入するインスタンスのライフタイム制御はデフォで、 永続的なシングルトンだけではなくセッション毎やリクエスト毎といった異なる スコープ単位でインスタンス生成して注入出来るのだが。 こう書いておけばメタクラスを駆使してライフサイクルのスコープを実装する例を 頑張って作るのだろうなぁ。どうやら簡単らしいし。
それくらい雑作無く実装できる事くらいコードみれば分かるだろ あ、読めないんだった
静的型言語では極一部のライブラリ実装者と 大多数のドカタという分業体制が成立してるから、 DIの実装すると聞くだけでドカタから見ると 壮大なことに見えてしまうんだろうね。 これは文化的な違いだから仕方ない。
>>842 > 普通にオブジェクトをセットするだけで済む簡単なお仕事なのに、なんでわざわざ
> リフレクションでロジックにホットパッチ当てるのに固執するのかよくわからんw
ライブラリ製作者側とライブラリ使用者側に
分けて考えましょう。
リフレクション云々はライブラリ製作者側です。
つまり、使用者側には関係ありません。
ライブラリ側が色々やってくれるおかげで
使用者側はシンプルで意図が明確なコードが書けるのです。
それがメリットだとわかりませんか?
>>844 > DIの実装すると聞くだけでドカタから見ると
> 壮大なことに見えてしまうんだろうね。
いいえ。壮大だと思ってるのは、貴方では?
だから、いま壮大だって思ってしまったのでしょう?
DIの個別の実装技術は簡単でも気の利いたDIコンテナの実装は案外面倒臭いな。
ツイのピーの人の上から目線すごすぎw
"使用側" exampl := DI TypeId0 new. "注入定義側" DI TypeId0: Integer. DI TypeId1: String. DIなんてこんなもんでいいだろ。 仰々しいライブラリーもいらん。
DIは仰々しいライブラリーではなく
まさに
>>849 程度のものだよ。
最初っからそう言ってるのに。
そんな程度のもので大騒ぎするJava業界ってマジうんこだよね
メタクラスで頑張ります君にも言えるけれども、単にnewするクラスを差し替えるとかロジックを 書き換えるとか、そんな話の時点であぁDIコンテナ使った経験が無いのだなぁと判る。 使った経験が無いから、DIコンテナのユースケースや依存性とは何かも理解していないでしょ。 クラスやロジックが変わらない場合もDIコンテナって使うんだよ。
内容の無い書き込みだなぁ。 DIコンテナどころかプログラムも書いた事無いSEが言いそう。
>>852 メタクラスに食いつき過ぎww
ていうか、ロジックを書き換えるって何の話だ?
お前のコードのロジックはnew演算子に依存してんのか?
>>851 DIで重要なのは、依存関係を内部から取り除くという考え方と
DIコンテナが、POJOを扱えるという点によって
変化した、継承が不要な(必要最小限でいい)設計手法
誰もDIの仕組みで大騒ぎなんてしてないよw
POJOかどうかなんてJava以外の言語にとっては どうでも良い実装の詳細 そんなものはDIという概念のメリットでもなんでもない
>>856 は、継承しまくりなんだろうなw
このメソッドは何処で定義してある?
ない。親クラスか? ない? 更に親クラスか? ない? 更に親クラスがあるぞ。さらに略
は?継承なんてウンコだろ
POJOかどうかも、依存関係の話の一つ。 親クラスに依存しているということ。 たとえばActiveRecordのように依存関係に ないものを継承てはいけない。 継承は、is-a関係にある場合に行う。 特定のモデルは、ActiveRecordと同じものか? 違うね。ActiveRecordの機能を使ってるだけ。 これはhas-a関係が正しい。 このように、フレームワークの規約によって 無理やり継承を導入させて依存するような設計は良くない。
ActiveRecodeは継承じゃなくてmix-inにするべきだし、Rails4では多分そうなる
仮にActiveRecordの実装が複数あったとして、 その二つを取り替えられるようにする。 そういう時、モデルが(自分自身で)mix-inするのではなく モデルが(誰かによって)mix-inされるという設計を取ると 二つの実装を取り替えられるという目的をスマートに達成できる。 これがDIの考え方。
>>860 mix-inしたとき、mix-inしたメソッドをprivateにできるのかな?
意図的にpublicにしたいならpublicにするのもいいけど、
ActiveRecordの場合、基本privateにするべき。
全部publicにしかできないなら、それはis-a関係と同じになってる。
・派生クラスにその実装を変更することなく異なる依存性を注入したい。 ・同じクラスであってもインスタンス毎に異なる依存性を注入したい。 ・状態を持った依存性を注入したい・例えばデータベースハンドラとか。 ・状態を持った依存性の場合、そのインスタンス生成を制御したい。 シングルトンだとかインスタンス生成をファクトリに委譲するとか。
良くわからんな規定Classを実行時に切り替えたいって事か? こんなんでいいだろ DI Type1 subclass:#Derived instanceVariableNames:'' classVariableNames:'' poolDictionary:'' category:'example'.
・プログラム内のレキシカルなコンテキストに応じて異なる依存性を注入したい。 アプリケーション毎にクラスAに異なる依存性を注入出来るのは当然として、同じアプリ内でも 例えばクラスAのインスタンスがクラスBのプロパティであるときとクラスCのプロパティである ときにはクラスAのインスタンスにそれぞれ異なる依存性を注入したい ・実行時のコンテキストやライフタイムに応じて異なる依存性を注入したい。 データベースハンドラのように実行中ずっと共有される依存性、セッション毎に共有される依存性 リクエスト毎に共有される依存性、使い捨ての依存性などの違いを手間をかけずに扱いたい。 ・そういった注入のされ方の詳細を注入される側には書きたくない。例えばインスタンス毎に 生成される依存性はnewで、シングルトンなどの場合はファクトリを、なんてのを注入される 側で書くのは最悪。注入される側にとっては注入される依存性がシングルトンなのか否かは全く あずかり知らぬこと。 ・依存性の注入し忘れをプログラム開始前に検出したい ・注入も出来るところは規約ベースなどで自動化したい ・等々といったよくある作業を新たに手組をせずに実現したい
悪くないけど生成のタイミングとオブジェクトの生成が 依存関係が取り除けてないのでDIとしてはまだ足りないな。 DIされる側のクラスは、DIされたオブジェクトが いつ生成されたのか(するのか)を意識してはいけない。 もしかしたらアプリの起動時に生成されたかもしれないし、 必要なときに生成時に作られたのかもしれない。 そしてこのオブジェクトはプロジェクト全体で一つしか 生成されないかもしれないし、複数生成されるかもしれない。 これらはシステム全体の依存関係を決めるときに考えることで、 単体のクラスで考えないほうが良い。(という設計方針がDI) 単純に言えば、依存関係を必要とするものは、内部でnewしてはいけない。 newは外部の「newマネージャクラス」という別名をあげたくなるような DIコンテナにやらせるということ。 FactoryはDIコンテナの一番シンプルな姿と考えていい。
868 :
867 :2013/03/02(土) 16:48:49.65
>>866 を見る前に書いちゃったけど
俺が言いたいことと同じような内容だな。
ぷぷぷ。メタクラスってまさに「newマネージャクラス」そのものなんだけどね ドカタ言語に無い概念だから知らなかったんだね
ぷぷぷ。gotoってまさに「例外」そのものなんだけどね まあ、こう言ってるのと同じ。 アセンブリ言語みればわかるように、プリミティブ(原始的)な機能でも複雑なことは出来る。 だけどそれでは、やれることが多すぎて間違った使い方をして、結果何がしたいのかわからなくなる。 まさにgotoと例外の関係と一緒。 C言語でエラーになったときはgotoで飛ばすと例外処理がスッキリとかける。 だがgotoはスパゲティコードの元。例外処理(try-catch)としてエラー専用の 機能があると意図が明確になり、間違った使い方も減る。 メタクラスもスパゲティコードの元なので、 意図が明確な機能に置き方方がいい。 メタクラスはライブラリを作るためのものと考え、 通常のアプリではメタクラスは意識するものではない。 ライブラリ内に隠蔽するものだ。 実際フレームワークを使った開発ではそうなってるだろ? メタクラスを使って、DIコンテナ(フレームワーク)を作れ。 そうすれば、意図が明確なコードが書けるようになる。
大抵の言語はnewをオーバーライドできるしねぇ
メタクラスがないドカタ言語ってなに? C#、Java以外の言語かな?
>>870 これがJava脳か。オブジェクトがインスタンスか
クラスで有るかなんてどうでもいいし
インスタンスかクラスかで区別するようなコードを書いちゃいけない
>>871 それはnewのオーバーライドではなく、コンストラクタのオーバーライドじゃないか?
Class1.new() したときClass1のインスタンスではなく
Class2のインスタンスができましたって言うのが
newのオーバーライド(でできること)なんだが。
>>873 レスが的外れ。
インスタンスかクラスかなんて話は全くしていない。
インスタンスという用語すら出ていない。
>>867 >FactoryはDIコンテナの一番シンプルな姿と考えていい
でも今度はファクトリが新たな依存性となるよねw
そして依存性毎にファクトリが立ち並ぶファクトリ地獄に。
そこでカスタマイズ可能なアブストラクトファクトリの実装と、注入される側の内部から
ファクトリの呼び出しを排除して、代わりに誰かが外部で呼んで注入する、その作業を
自動化する仕組みを提供しているのが現代的なDIコンテナかと。
>>874 object := Class.
object new.
object := Factory new.
object := object new.
やっぱJava脳だね〜
Perlはnew()がそもそも無くて、単によく使われる名前ってだけの ただの関数だからnewのオーバーライドできるよ。 Package Class1 sub new { return Class2->new(); } 1; こう書くと my $c = Class1->new() したときに $cはClass1とは無関係な、Class2のインスタンスができる。 混乱したのなら、こう読み替えればいい。 Package ClassFactory sub create { return Class2->new(); } 1; my $c = ClassFactory->create() で、これがDIコンテナのシンプルな形。
newをオーバーライドできて、さらに実行時のスタックフレームにアクセスできて コンテクストに応じた注入ができれば、内部でnewしててもDIできる ただのシンタックスの話
オブジェクト生成をオーバーライドできる言語 Smalltalk Perl Python Ruby Go Javascript Lisp 単にC++系統のやり方が少数派なだけだろ
誰もDIが出来る出来ないなんて話はしていない思うよ。
>>866 も含めて全部出来て当然。
ただ手軽にやりたいし車輪の再発明はしたくないから、DIコンテナを拾ってきて使う。
ではPerlのnewのオーバーライドから、DIコンテナの話につなげていくよ。 my $c = ClassFactory->create() これがDIコンテナのシンプルな形と言った。 それっぽく名前を変えると、 my $c = DI->create() だな。DIを使ったクラスを書いてみる。 package My; sub main { my $c = DI->create(); $c->foo() } この欠点はmainを呼び出した時に$cが作られるということ。 DIの発想では$cは「誰かが作ったもの」であり生成のタイミングは Myクラスを書く人が考えるべきことではない。 あと単にcreateメソッド(new)呼び出しを書くのが面倒というものもあるw この場合は引数なしからいいけど、何度も同じ引数でnewするの面倒でしょ? ってことで、DIを使ったコードはもっとシンプルにこんな感じになる。 (Perlのコードとしてはちょっとおかしいけど、説明のための不要な冗長コードを削ってる) package My; sub main { $c->foo(); } $cは誰かが生成してくれたもの。このコードからは、誰が生成したか いつ生成されたかなどという「依存情報」がなくなった。
C++系統以外なら大根なくても手軽にできるがな 大根入れるのもメンドクセ
DIが手軽にできるなら、DIやればいいと思うんだが? なんでいちいちnewするんだろ? 「誰かが生成してくれたもの」として コーディングしてる例が少なすぎる。
>>866 範囲を限定した文脈での依存性注入ってのを
具体的にコードで書いてくれるか?
何か回りくどいこと考えてる気がする
DIが手軽にできるのに、DIしないのは まだDIの発想に追いついてないからだと思う Javaなどでは、まず最初にDIの発想があって それを実現するために、DIコンテナができた。 静的型付け言語では難しいからね。 それをみてDIコンテナを作ることがゴールだと 思った人たちが、動的型付け言語ならDIコンテナ不要だよと言い始めた。 それはそれでいいんだが、DIコンテナの実装という話で終わって、 DIの発想にはまだたどり着けない。 DIの不要ではなく、DIコンテナ不要になっているのがいい証拠だ。 DIコンテナがあることでDIの理解につながると思うが、 さてDIコンテナなしで、なんでもできるアセンブラのよう機能を使って 高級言語的機能を理解できるようになるだろうか? 不可能ではないけど、たどり着けない人が多そうだ。
>>887 newするというコードが持っている
依存関係を外部に「置き換える」というのが
DIの本質。
newしてる行をその場で別の書き方に置き換えてもダメ。
newしてる行そのものを消し去って、クラス外に書くことが重要。
>>886 まさにこれ
package My;
my $c;
sub main {
$c->foo();
}
$cは中で生成していない(なのになんで使えるんだ!?)
外部から注入しているからだよ。
だって依存性書き換えたくなったら後でクラスオブジェクトを 置き換えりゃ済むもん 無意識にできるから意識する必要ないもん
無意識にできても、コード書かないといけない。 それは無意識ではない。
最初に書くか、後で必要になってから書くかの違い
>>889 だから簡単に出来るじゃん
newはオブジェクトにメッセージを送ってるだけ
じゃそのメッセージの送り先となるオブジェクトを
プログラムの起動時点で置き換えりゃいいだけ
>>894 お前が言ってる、簡単にできるというのは
「DIコンテナ」の機能。
DIは考え方だ。
依存性の向きがどっち向きかいう以前に、そもそも依存していない
>>892 じゃそんな事できるツールなんて存在しなくね
大根ツールだって大根入れにゃならんし
設定も書かにゃならん
コードにも手を入れにゃならん
実態のクラスとnewメッセージが送られるクラスの
対応をマッピング用のスクリプトにまとめとく
ほうが遥かにマシだろ
>>895 だから何?
そもそも静的型じゃないとDIし辛いとか
アホみたいな発言から始まった議論だろ
DIコンテナについて語っている人はだれもDIの実装が難しいとか言っていないと思うのだけど
> だから簡単に出来るじゃん
>>894 のいう「簡単にできる」と
俺の「簡単にできる」とでは求めてるレベルが違う気がする。
俺が言いたいのは、もっと簡単にできるよね? だ。
例えば、変数の値が数値かどうかを判定するのは、
正規表現で「簡単にできる」それが
>>894 が言ってるレベルで
俺はIsNumberという関数を作れば「もっと簡単にできるよね?」ということ。
メリットは簡単にかけるというだけじゃない。文字列でやる正規表現と違って
関数ならコンパイルチェックも出来るだろうし、修正が必要なとき
関数内部を修正するだけでいい。数値チェックをしている場所を探すのも簡単だし、
バグへの対応やメンテナンス性というメリットがある。
だがそれでも
>>894 は(正規表現や自分でコードを書いて)簡単にできる。と言うのだろう。
>>898 > DIし辛いとか
> アホみたいな発言
それどれ?
DIという考え方の話をしていたら
DIコンテナは動的型付け言語で簡単に実装できるって
話からずれていったんだろ?
DIの話が出たのは、
>>800 からかな?
動的型付け言語では、DIコンテナの実装も簡単だし DIコンテナがなくてもDI出来ると思うけど コードのドキュメント性からいったら DIコンテナがあったほうがいいかな コードのドキュメント性というのは コードにコメントを書くのではなく、 コードそのものが、ドキュメントとして読みやすいという意味。 例えば、IsCreditCardNumberなら、クレジットカード番号チェックだなってわかるけど それを正規表現で書いても、クレジットカード番号なのか、電話番号なのか すぐにはわからないでしょ?
>>901 DIコンテナ使うほうが「よっぽど正規表現を
使えば簡単にできる」になってるだろ
型を間違えればエラーになるのは動的型だろうが
静的だろうがかわらん
かと言って依存性をクラス内から排除するのも
クラスかオブジェクトであればDIコンみたいな
もので無理矢理排除するんじゃなく
自然に排除できる
こういうファイル名でマッピングテーブルを用意しましょうとかいう オレオレDIコンテナモドキ規約を作るよりも、 有名なDIコンテナを使ったほうがいいと思うよ。
>>903 大抵インタープリターだからスクリプトにマッピング
書いてimportすりゃ十分でしょ
使う側も代入しか書いてないから意味がすぐわかる
>>904 いや、だからDIは考え方で
DIコンテナはその考え方を実践するための道具
DIコンテナは依存関係を無理やり排除する道具ではなく、
依存関係を外にだすときに使う道具だよ。
お前DIコンテナの役割すら間違ってるじゃん。
>>906 コードを読めば意味がわかる
正確に言えば、コードを読まないと意味がわからない。
読んだ所で、なんでこんなコードになってるの?
あほじゃねって思われるだけ。
そこでDIのためにこのようなコードになってますと
君はコメントを残すわけか?
コメントには、コードの動きを書くのではなく
どうしてそのようなことをしたのか、
その意図を書くものだからそれは正しいな。
でも、コメント無しで、コード見ただけで
その ”意図” がわかるならそのほうがもっといいんだよ。
>>907 だからどうしたんだよ
ここでDIは考え方だって言われても話が
つながってないだろうが
そもそもクラスオブジェクトが使えりゃ
DIがDIコンより簡単に出来るって言ってるんだ
最初からDIコン=DIになってないだろ
>>908 可読性は別問題だな
可読性の主義によってはOOとも
背離するし別議論だ
>>903 number instanceof CreditNumberの方が分かりやすいかな
>>908 良くも悪くも普通にnewしてるように見えるんだから
読む側がロジックを追うときにDIコンテナの存在を意識する必要はない
DIコンテナ側のコード読むときは、そりゃ意味わかるだろ
代入してるだけなんだから
>>909 > DIがDIコンより簡単に出来るって言ってるんだ
できないよ。できるというのならnew使わないで
newしてみ。
今、お前が頭のなかで考えたのが、
DIコンテナだから
>>912 > 良くも悪くも普通にnewしてるように見えるんだから
DIの考え方に反してるじゃん。
newしてなくても使える。なぜだ
外部から注入しているから。
なるほど、newするのを意識しなくていいんだね。
それがDIの考え方。
newしてても依存してないんだっつーの
>>915 そうではなく、newそのものを忘れてくださいってのがDIです。
それは手段が目的になってる じゃあnew演算子が無い言語はどうなるの?
DIってクラスから依存性を排除し 実行時とか後天的に依存性を注入出来るって事じゃなく 単にnewを使わない事だったんだ(衝撃)
そうかJava厨にとってDIはnewを使わないって概念だったのか 通りで話しが食い違うわけだ()
コードを見た時に思ったここと 反する動きをしてはいかんよ。 newって書いてるのに、実はnewしてませんでしたとか 罠以外のなにものでもないから。 こういうのを可読性というんだがねぇ。
普通にnewしてたと思って読んでも全く問題無いんだよ それが抽象化ってもんだろうが
922 :
デフォルトの名無しさん :2013/03/02(土) 18:39:54.38
結局宗教の優劣は信者の数 OSが書かれている言語がCであるという意味はあまりに大きい。
>>917 > じゃあnew演算子が無い言語はどうなるの?
new演算子はオブジェクト生成の手段だ。
new演算子がなければ、同じ目的の物の話に置き換えれば良かろう?
>>918 > DIってクラスから依存性を排除し
> 実行時とか後天的に依存性を注入出来るって事
あってますよ。
>>919 >そうかJava厨にとってDIはnewを使わないって概念だったのか
ぷw オブジェクトの生成が外部でやるからnewがでてこなくなるだけだよw
>>921 > 普通にnewしてたと思って読んでも全く問題無いんだよ
それだめじゃん。
newがまったくでてこなければ、
いつ生成されたかなんて考えることが出来ない。
newしたと思っているのなら、その時にnewされたはずって思ってしまう。
例えばnewされた時にこの処理やってるのだからって勘違いしてしまう。
>>923 DIコンテナを使わなくても、newを使ってても
クラスから依存性を排除できるし、実行時とか後天的に依存性を注入出来る
という話に対し、newを排除するのがDIだと
>>916 が言い出したんだろうに
>>924 プログラマがそんなレベルじゃメッセージ転送を使ったコードは読めない
話にならないよ
>>920 factory := Factory new.
object := factory new.
よく有るパターンだがどの辺が罠よ?
因みにSmalltalk系統だとnewを直接使うことは少なくて
生成メソッドで代用する
type := Type.
object := type typeWithValue:0.
type := Factory type.
object := type typeWithValue:0.
>>927 Factoryを使う所が罠。
その時点で生成していると
思ってしまってる。
生成タイミングを意識している時点で
DIにたどり着いていない
smalltalk系統だとnewってのはラッパーで 実際オブジェクト生成するのはprotoNewとか そんなんだったりするんだよねー 言語的に最初からオーバーライド前提の仕様なんだよねー
>>920 がシングルトンすら知らないことは確定的に明らか
あんなもん知らんでもいいけどMonoStateはしっといて欲しい
プログラマが「生成している」と思っている・・・だけど実際にはされていないかもしれない のと プログラマが「誰かが生成している」と思っている では全然意味が違う。前者は自分の意図に反する動きをしており、 後者は、自分の意図に反していない。
OOに向いてねぇって CでもBasicでもやってなよ
COBOLが一番向いてるんじゃねぇか? 読んだまんまで可読性抜群だし Javaは現代版COBOLとも言われるしな(笑)
937 :
デフォルトの名無しさん :2013/03/02(土) 19:40:37.20
CでOO出来ないと思ってる奴がいる・・・
COBOLでもOOできるらしいぞ そうじゃなくて出来るだけOOしない言語使えば ってことだろ
>>927 DI的にはファクトリに依存しているので依然ダサい。
"依存排除側" object := DI type1 new. object := DI type2 typeWithValue:0. DI type3 subclass:#type instanceVariable:'' classVariable:'' poolDictionary:'' category:'Independency'. "依存注入側" DI type1: Integer. DI type2: TypeForIntegerFactory. DI type3: Integer. "或いは" delegate := Factory new. DI type1: delegate. "別解としてClass辞書を直接書き換えてしまう" OldType := Type1. System classDictionary replaceClass: #Type1 ToClass: #Integer. 依存性排除するにゃ大体これだけできりゃいいんでしょ
既存のDIコンテナでは注入先ごとに異なるコンストラクタ引数を指定して注入 することも多いのだけれども、newを使う場合はどう簡単に書けるのかな。
依存性を別のオブジェクトに委譲するなんてのはJavaに限らずどんな言語やフレームワークで 大概やられていること。以上した依存性を解決するのも内部からファクトリ経由で引っ張って きたり外部から注入したりと、フレームワークの実装を覗いてみれば色々やられている。 例えばデータベースのハンドラなんかはJavaの世界でも委譲される依存性の筆頭格だけれども これはActiveRecordにしてもデータベース接続は別オブジェクトに委譲されていて、その解決 もプールから普通にインスタンスを引っ張ってくる仕組み。別にnewの書き換えとかしていない。 DIはnewのゴニョゴニョ云々で出来ると言っている人は単に腕自慢ではなくて、実際に広く使わ れているフレームワークでその手法がどの程度活用されているのかコード例を示してもらえると 助かる。
"注入側" DI type1: NewDelegate withBlock:[Integer integerWithInteger:0.]. "依存排除側" DI type1 new."Integer integerWithInteger:0.の戻り値が返される" ね。簡単でしょ。
>>942 ActiveRecodって局所的な意味になるから
メッセージ転送って言ってくれないか
メッセージ転送ならWikipediaにも乗ってるし
複数の言語で使える
>>942 一言言っておくわ、
お前が言ってる依存性ってのは
DIで排除しようとして依存性と全く関係ない。
DIコンテナを簡単にできるといっても DIの考え方にまでいたらないのは面白いね。 手段(DIコンテナ)と目的(DI)が 逆になってる。
>>945 は?ActiveRecordの振る舞いはデータベースハンドラに依存しているでしょうが。
DIで排除しようとしている依存性って何だろう?
大根に拘らず依存性を後で簡単に注入する 例はこのスレに幾つか出てるだろ お前はどういう結論に持っていきたいんだ?
>>947 一部のクラスじゃ無くて自分が作ったクラス全てを
他のクラスから独立させ、実行時に全ての依存性を
注入するって事じゃないかな
既に何個かこのスレでも例はでてる
>>947 1.継承をやめること。is-a関係ないものは継承させない
2.あとでなw
Diするのに継承止めるってのはJava固有の事情だろうが 動的に継承できるなら関係ねえ
>>951 言っとくが、実行時に継承するのも無しだよw
(当たり前だけど、is-a関係にないものの話)
>>945 データベースハンドラを排除されるべき依存性だと見られないのであれば驚きだわ。
単にクラスの実装を入れ替えるだけがDIだと思っているのなら勘違いも甚だしいし、DIコンテナ
のユースケースが本当にわかっていない。
>>952 何故?それこそDIを無視してDIコン実装に依存してるだけだろ
手段が目的になってる
目的は依存を排除する事のはずだ
>>954 コンポーネントの実装はDIコンテナの実装に依存しないよ。
ふざけるな! DIコンテナを使ってるくせに DIコンテナに依存してないわけがないだろ!
>>955 継承に制限がある時点でもろに依存してるじゃねぇか
結局あれだろJavaは簡単に動的継承できねぇから
継承元を依存注入対象にできませんってだけだろ
要は純粋な依存性注入はJavaじゃ出来ませんって話だ
>>957 はいったいDIを何と勘違いしてるのだろうか?
そもそも抽象化クラスの型名を宣言時に書かなきゃならん時点で 純粋なDIなんて無理。純粋なDIをするなら 動的型付けかgoみたいな方法を取るしかない
動的言語ってクラスにメソッドを生やすのは得意だけど クラスにメソッドをはやさないことにメリットが有るって 気づいていないのかな? 何でもかんでも、メソッド生やしてバカみたい。 必要ないメソッドはむしろ生やしたほうが デメリットが有るというのに。 カプセル化もそうだよね。外部から見せないという メリットがわかってないとしか思えない。
>>956 依存しないよ。DIコンテナ無しでも実行できるよ?
>>961 動的言語の代表格であるシェルスクリプトさんには
メソッドなんてありませんよ。
代わりに関数とかコマンドは有りますが。
>>963 Dependecy Injection
純粋な依存性の注入とは全ての依存性を後で注入できる状態
不順な依存性の注入とは一部の依存が残ってて
後で依存性を注入できない状態
>>964 そのシェルスクリプトの話してるの?
mix-inとかできるレベルの言語の話だと思っていたんだが?
>>966 皆は動的型付け言語の話をしているね
君は動的言語が気になるらしいけど
>>967 おかしいなぁ?w
動的言語
抽出レス数:56
動的型付け
抽出レス数:36
所で動的型付け言語の
スクリプトってどれだ?
動的型付け言語っていうのは、 型付けが動的であるということ、 つまり型が存在するということ。
しぇ、しぇるすくりぷとにだって 型はあるんだからね!
>>968 動的型付だとJavascriptかな
PerlやPythonとかは俗にScriptと呼ばれる事もあるけど
公式には汎用言語(Genral-purpose language)てScriptじゃないらしいし
>>968 この動的型付言語スレができた歴史をしらん奴らが増えたな
その昔動的言語はダメだの云々のスレがあった
その中で動的言語と動的型付言語は別物だろという揉め事が起きた
そのうち動的型付け排斥派が動的型付隔離スレを立て動的型付を排除
その後その動的型付スレを継承する形でこのスレが生まれた
動的言語、動的言語連呼してるとそのうちまた隔離スレができるぞ
>>971 え? シェルスクリプトの話でしょ?
>>964 > 動的言語の代表格であるシェルスクリプトさんには
ほら。
>>973 シェルスクリプトは動的言語だけど
殆どは動的型付じゃないんじゃない
HyperShellだっけ?あれは動的型付言語兼動的型付言語かも知れないけど
でも君が聞きたかったのは動的型付言語じゃなく動的言語だよね
> シェルスクリプトは動的言語だけど っていうか、静的型付け言語も ほとんど、動的言語じゃないか?
動的言語のリスト
http://en.wikipedia.org/wiki/Dynamic_programming_language ActionScript
BASIC
BeanShell[3]
Clojure
ColdFusion
Common Lisp and most other Lisps
Dylan
Groovy[4]
E programming language
Fancy
Java programming language
JavaScript
Julia
Lua
MATLAB / Octave
Objective-C
Perl
PHP
Powershell
Python
R
Ruby
Smalltalk
Tcl
VBScript
そんなTalkで揉めに揉めてる記事だされても… 半年後にはまるごと消えるかもしれんぞ
揉めていたとしても、 直すまでもないという話だから この状態になってる。 現状を受け入れよう。 受け入れられないのなら 自分で変えよう。
Pharo関係で話題に上がってたがそもそも依存性の注入が意識されるのは その言語が仮想classを搭載してないからだそうだ。仮想classを搭載してれば依存性の 注入なんて普通の事過ぎて名前が与えられる事もないと。
低能でも扱える機能だけをSmalltalkとC++からピックアップして作られたのがJava 何が出来るかという観点で戦ったら勝負になるわけない
あいもかわらずクラスの話しか思いつかないんだな・・・
そもそもクラスという用語から思い浮かべるものが違うと思うぜ 出来る事が全然違うんだから
結局「僕が考えるDIはこんな風に出来るよ!」と出てきた例はことごとくファクトリを使ったパターンの派生。 これを見てもDIコンテナの現状や歴史的経緯がわかっていないと思われる。
クラスの問題では無いな 単にオブジェクト生成の仮想化で リソースやその他の依存性も一緒に片付くから 仮想クラスとかの話してりゃ十分なわけで
依存性を解決するのに何故内部でnewやファクトリの類を呼び出すのはダメで、コンストラクタ 引数やセッターといったインターフェイスをわざわざ宣言して注入するのか、理由を理解して ないでしょ。これ動的静的とか仮想クラスとかとは全く無関係な明確な理由があるから。 書かれた例も歴史的にアンチパターンとして既に否定されたものから一歩も出ていないんだよね。
なんか言いたいんなら具体的にコードで書いてみたら? こんなケースの場合は依存性があってどういう問題があるとか 端から見て何を訴えたいのか分からん
なんかDIについて言いたいなら具体的に適当なDIフレームワークの解説記事や チュートリアルでも読んでからにしたら? Factoryの類の内部呼び出しがダメな理由も知らずにDIについて語ってきたわけ?
どのクラス(モジュール)やリソースにも依存しない クラス(モジュール)があったら便利だよね。 依存してる部分を利用者が後で自由に変更できて バグ付きのコンポーネントとか存在すると解ってて 野放しにする必要がなくなる。 あと、ファクトリーを使ったときだと、 既に組み上がってるクラスを作り直すのが難しい 処理の切り替えや新しいクラスを作るときにしか 活躍できず、深い所にあるオブジェクトは手をつけ辛い それじゃ、そういう問題の解決策の一派を総称してDIとよびましょう。 これだけの話じゃないのか? だから仮想クラスが存在するなら意識する必要がないと言われるんだろ
>>988 君らの言ってるFactoryはこのスレに出てきたどのFactoryを言ってんだ?
>>979 > DIはJavaで流行ってる用語だから
> Javaで出来ないことはDIに含まれない感じになっちゃってるんだよ
それ単にJavaよりか遅れてるってだけだよw
ウェブフレームワークなんかも
Javaの世界ではとっくにあったのに、
比較的最近取り入れられた。
PHPの世界で最近やっとDIが話題になり始めてるらしいよ。
このスレJavaしか出来ないヤツはいても Javaが出来ない奴は居ないからな 単にJava厨がFactoryという文字を見つけて さわいどるだけかもしれん
Java厨がこんなんじゃMartin fowlerも草葉の陰で泣いとるわ
Java知ってるけど JavaScriptも知ってる? というかウェブ使うなら 絶対JavaScript知ってるはずなんだが? Javaしか知らないってどこから出た妄想だよw
>>990 ざっと見てみたけれども大文字小文字に関わらず「出来るよ」サンプルにかかれている
factoryは全部ダメだね。ファクトリの内部呼び出しを排除してDIに至った理由が全く
理解されていない。
JavaScriptにもDI活用したフレームワークがあるな。
>>996 何が気になるんだい?具体的にどう困るのか言ってみそ。
言えないなら脳内理論に浸ってるだけだぞ。
結局、Java厨は型にはまってただけ
>>989 長々とオレオレDI定義をご披露する前にちゃんと下調べしたら?
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。