はてなキーワード: Stringとは
英語の不規則動詞はおおまかに,過去分詞がtかdで終わるもの(以下dtタイプ)とnで終わるもの(以下nタイプ)に分けられる。ほとんどのdtタイプの動詞は過去形と過去分詞形が同じ形で,A-B-B(一部はA-A-A)のように変化する。また,原形の末尾がdかtの不規則動詞はほとんどがdtタイプに属する。(例外:eat,get,bid等)一方,ほとんどのnタイプの不規則動詞は原形,過去形,過去分詞形がすべて異なり,A-B-Cのように変化する。
原形から過去・過去分詞形になるときに起こる変化は基本的に母音が変化するか末尾にdtnが加わるかの2種類,あるいはその両方で,原形にあった子音がなくなることは原則としてない。(例外:-ught型,went,had,made)
分類は以下の通り
become,forgetなど末尾にほかの不規則動詞を含むものは省いた。
表中の*は規則変化もし得ることを,#は他の不規則変化もし得ることを,!は意味によって変化が異なる単語であることを示す。
すべてdかtで終わる。特に末尾tで短母音のものが多い。get,sitが含まれないことに注意。形が1種類で覚えやすいが,英文中の「have put」「is put」等を見てもビビらない心構えが必要。
bet * | bust * | cast | cost | cut |
hit | knit! | let | put | quit * |
set | shit *# | shut | sweat * | thrust |
wet* | burst * | hurt | beat # | bid # |
clad | glid * | rid* | shed | spread |
wed* |
原形がdで終わる動詞が母音を変化させて過去形・過去分詞形になる型。最後のplead,readは発音のみ変化する。
breed | bred |
feed | fed |
lead | led |
plead *# | pled |
speed ! | sped |
tread # | trod |
bind | bound |
find | found |
grind | ground |
wind | wound |
chide *# | chid |
slide # | slid |
hold | held |
stand | stood |
abide * | abode |
plead *# | plead |
read | read |
原形の末尾のdがtに置き換わり,それ以外は綴りも発音も変わらない。endで終わる動詞が多いが,end自体は規則動詞。原形のほうが過去形っぽく見えたりするので注意が必要。逆パターン(At-Ad-Ad)は存在しない。
bend | bent |
lend | lent |
rend | rent |
send | sent |
spend | spent |
build | built |
geld * | gelt |
gird * | girt |
【Ad-Bd-Bd】の末尾tバージョン。get,sitはこちらに含まれる。
fight | fought |
light * | lit |
meet | met |
shoot | shot |
get # | got |
shit *# | shat |
sit | sat |
末尾にdが加わるという点で規則動詞に近いが,付き方が特殊で母音も変化する。
lay | laid |
pay | paid |
say | said |
sell | sold |
tell | told |
hear | heard |
flee | fled |
shoe * | shod |
baa * | baa'd |
make | made |
have | had |
末尾にtが加わる。原形の/iː/が/e/に変化するものが多い。
feel | felt |
keep | kept |
sleep | slept |
weep | wept |
creep | crept |
kneel * | knelt |
sweep | swept |
leave | left |
bereave ! | bereft |
cleave *# | cleft |
deal | dealt |
mean | meant |
dream * | dreamt |
lean * | leant |
leap * | leapt |
lose | lost |
spoil * | spoilt |
burn * | burnt |
learn * | learnt |
dwell | dwelt |
smell * | smelt |
spell * | spelt |
spill * | spilt |
drip * | dript |
grip * | gript |
wrap * | wrapt |
pen * | pent |
末尾が-oughtか-aughtに変化する。どちらも発音は/ɔːt/。wentを除けばもっとも原型をとどめない変化が起こるので過去形から原形を思い出せるようにしておく必要がある。
beseech * | besought |
bring | brought |
buy | bought |
overwork * | overwrought |
seek | sought |
think | thought |
catch | caught |
teach | taught |
過去分詞形が原形+nとなるもの。過去形では母音が変化している。fall,eatにはenが,do,goにはneが付くことに注意。
blow | blew | blown |
grow | grew | grown |
know | knew | known |
throw | threw | thrown |
draw | drew | drawn |
shake | shook | shaken |
take | took | taken |
drive | drove | driven |
rise | rose | risen |
strive | strove | striven |
thrive * | throve | thriven |
see | saw | seen |
give | gave | given |
eat | ate | eaten |
fall | fell | fallen |
do | did | done |
go | went | gone |
【A-B-An】の亜種で,showに代表される過去形が規則変化(-ed)になっているもの。
grave * | graved | graven |
hew * | hewed | hewn |
mow * | mowed | mown |
prove * | proved | proven |
saw * | sawed | sawn |
sew * | sewed | sewn |
shave * | shaved | shaven |
show * | showed | shown |
sow * | sowed | sown |
strew * | strewed | strewn |
過去分詞形が過去形+nとなるもの。eが脱落するtear-tore-tornのパターンに注意。wakeはtake,makeと異なり,この型に属する。
break | broke | broken |
cleave *# | clove | cloven |
freeze | froze | frozen |
speak | spoke | spoken |
steal | stole | stolen |
weave ! | wove | woven |
shrink # | shrunk | shrunken |
wake | woke | woken |
bear ! | bore | born |
swear | swore | sworn |
tear | tore | torn |
wear | wore | worn |
bear ! | bore | borne |
原型にd,tを含み,過去分詞形でそれが重なるもの。get以外は【A-B-An】に近いがgetは【A-B-Bn】に近い。
smite # | smote | smitten |
ride | rode | ridden |
write | wrote | written |
bite | bit | bitten |
chide *# | chid | chidden |
hide | hid | hidden |
slide | slid | slidden |
bid # | bade | bidden |
forbid # | forbade | forbidden |
forbid # | forbad | forbidden |
get # | got | gotten |
過去分詞形にnが付くが,【A-B-An】でも【A-B-Bn】でもないもの。
fly | flew | flown |
lie | lay | lain |
slay | slew | slain |
shear * | sheared | shorn |
swell * | swelled | swollen |
tread # | treaded | trodden |
原型にiを含み,それがi-a-uと変化していくもの。わかりやすい変化だが数は少ない。
begin | began | begun |
drink | drank | drunk |
ring | rang | rung |
shrink # | shrank | shrunk |
sing | sang | sung |
sink | sank | sunk |
spring # | sprang | sprung |
stink # | stank | stunk |
swim | swam | swum |
dt型でないが,A-B-CではなくA-B-Bと変化するもの。末尾が-ingのものが多いが,bringやring,singが含まれないことに注意。
cling | clung |
fling | flung |
sling | slung |
slink | slunk |
spling # | splung |
sting | stung |
stink | stunk |
string | strung |
swing | swung |
wring | wrung |
hang ! | hung |
dig | dug |
stick | stuck |
strike | struck |
heave ! | hove |
reeve * | rove |
stave * | stove |
shine ! | shone |
win | won |
dive * | dove | dived |
smite # | smote | smit |
beat # | beat | beaten |
come | came | come |
run | ran | run |
最近ふと思った
「感じる」っていう関数を考えると、こう書ける
感じる(x)
xの型はもちろん「感じるもの」だ
感じる(カンジルモノ x)
しかし、人間の脳は多態性を担保してるので、実際には動的型付けに近い
感じる(var x)
例
・感じる(暖かさ)
・感じる(力強さ)
・感じる(お昼ご飯)
・感じる(猫)
・感じる(波)
人の脳内で渡されたオブジェクトをカンジルモノにキャストする(解釈する)
この時、当たり前だが渡されるものはカンジルモノである方が、受け手にとっては簡単だ。
つまり
感じる(◯◯感)=◯◯感を感じる
「かっこいいコード」をありがたがり、「分かりやすいコード」を否定するプログラマーがいるが
あれと同じだ。
ちなみに、感じる(◯◯感)に、そのまま◯◯感を入れるのはバカっぽいというのは分かる
isEmpty(String x)に、isEmpty(string)と渡すより、isEmpty(name)などと
今回の場合はisEmpty(nameString)に近いが。
ただ、「渡すものがnameStringという名前だからisEmpty(String x)よりisBlank(var x)に渡したい」
「違和感が◯◯感だから、『感じる』じゃなく『覚える』を使おう」
という主張はそういうことを言っているのだ。
と言うわけで「違和感を感じた」はそれほど悪くないと思う
newしてから渡せば良いと思うよ。
いちいちクラスに分ける理由は、こういう感じで、クラス内の変数にアクセスすれば、画面事の表示とかが簡単に出来る的な?
// Javaの書き方しらん、インターフェースを実装することを定義したい
public class EventHoge : View.OnClickListener {
//画面事の名称
// Javaの書き方しらん、インターフェースのメソッドを実装することを定義したい
public void View.OnClickListener.onClick(View v) {
AlertDialog.Builder dlg;
dlg = new AlertDialog.Builder(MainActivity.this);
dlg.setTitle("画面の名前:" + ViewName); // 画面名称が表示されるイメージ
dlg.setMessage("Hello, サンプル!");
dlg.show();
//<ーー
}
}
// Androidなにも知らんけど、元増田がボタンにイベントを書く処理が書いてあるクラスのことが言いたい
// そのメソッド
final Button button = new Button(this);
button.setText("ダイアログの表示");
View.OnClickListener ocl = new EventHoge();
ocl.ViewName = "画面その一";
button.setOnClickListener(ocl);
}
}
こんな感じにすれば、画面が二つあって、
その画面の名称を表示するようなボタンを、二つメソッドをコピペして作らなくていい的な?
サンプルは、出来るだけとっちらかさないよう、匿名クラスとか使って、サンプルで紹介したいところ「だけ」を書くんだよね。
だから、そのサンプルがどういう意味かをちゃんと読み取って、自分ならこう書くとか、こう書けるか? とかを考えてこそ勉強だと思うよ?
今回のレイだと「View.OnClickListener」っていうインターフェイスを実装したクラスを、setOnClickListenerすればいいってことさえわかれば、
匿名クラス?(っていうのかな? ちょっと用語はよくしらん、クラス定義を使い回さず、その場だけのクラス定義を書く書き方)とかを使わずに、
どういうふうに応用ができるか? とか頑張れ!
頑張れ!
頑張れ!
はああああああ。
おれはビールを飲む!
私はコミットログの書き方に悩む英語の苦手な人間である。実際、似たような人は世の中に結構いるようで、頻出単語を集計したりまとめたものは既にあって役に立つのだけれど、これらはあくまで単語の話であり、具体的な文を構成する過程でやっぱり困る部分がかなりあった。
要するに、どういう時にどういう文が使われているのか、ということを示した例文集が欲しいのである。ググると他にも「例文集があればいいのに」みたいな声はあるくせして、しかし誰も作ろうとしない。何なんだお前ら。それじゃ私が楽できないじゃないか。
ここで挙げているコミットログは全て実際のコミットログからの転載である。当然ながら各コミットログの著作権はそれぞれの書き手にある。いずれも各英文でググれば出てくるし、フェアユースの範囲なら許してくれるだろうと考え名前とプロジェクト名は割愛したが、ここにお詫びと感謝を述べておきたい。
抽出条件だが、参考にできそうなコミットログを多く含んでいそうなリポジトリをGitHubのSTARの多い方からざっと目で見て適当に選び、それぞれ最新コミットから5000件抽出した(あわせて前処理として、コミットログ冒頭のタグ情報は消去した)。
atomのみ5400件抽出していたため、計25400件のコミットログがベースである。このうち、以下の条件に合致するものは参考例にすべきでないとして一律排除した。
こうして残った8540件を眺めながら、適当に切り出したのがこの用例集である。個人的に「うーんこの」と思った表現も、散見される場合は載せた。
ということで、以下用例を羅列していく。
以上の用例をふまえ、今回の参考ログ8540件から先頭の単語を出現回数で並べると次のようになった。
Add | 1149 |
Fix | 1014 |
Update | 584 |
Remove | 566 |
Use | 382 |
Don't | 260 |
Make | 228 |
Move | 178 |
Change | 103 |
Rename | 85 |
Improve | 76 |
Avoid | 68 |
Allow | 65 |
Implement | 60 |
Handle | 58 |
コミットログの基本形はもちろん動詞 + 名詞である。名詞は固有名詞、複数形、不可算名詞が多いが、単数形の場合の冠詞は a が使われるか、あるいは省略される。the はまず使われない。
何かを追加した、という表現では非常に広く Add が使われる。メソッドからテスト、ドキュメントに至るまで大概これでまかなえる。
一方、何かを修正した、という表現では広く Fix が使われる。「何か」は typo や crash といった単語からメソッド名まで幅広い名詞を取るが、動名詞はあまり取らないのと、that節は取らないのでその点は注意が必要である。
Fix は「何かが正しく動くようにした」ことを示し、正しい動作内容が何かを説明しない。そこで正しい動作内容に言及したい場合は Make sure が使われる(こちらはthat節が取れる)。ただし Fix よりもニュアンス的に重い表現と思われ、Fix を使わず Make sure ばかり使うのはちょっとキモいのではないかと思う(Ensure はさらに重い表現っぽい)。
また、Fix は typo 以外でのドキュメント修正に対して使われることは稀である。対して Update はドキュメント、コメント、テストに使われ、本体のコードの修正に対しては使われない。本体コードの修正にあわせてテストも更新したなら Update が使われる。ただ、テスト機構それ自体のバグを修正したなら Fix である。
無駄な何かを単純に除去したなら Remove を使う。これまでのもの(A)から別のもの(B)に切り替えたのであれば Use B instead of A か Change A to B が使われる。新たに何かを利用するようにしたのであれば Use を、利用を取りやめた場合は Don't use を使うことが多い。
何かをしないようにしたなら Don't を、内部実装の効率化なら Make A + 比較級/形容詞 か Improve が使われる。
中身の変更を伴わない単なる名前の変更なら Rename A to B、コードや機能の論理上の場所を移動させたなら Move A to B である。
この辺はリファクタリングと呼ばれる行為と思うが、Refactor というぼんやりした動詞はあまり使われず、このように変更内容の種類に応じて動詞が使い分けられている。
コミットログにはWhyを書くべきだ、というのを何かで見かけたので because とか since を使ったログがどの程度あるかを調べたが、8540件のうち22件だった。基本的に短く、シンプルに、一目で意味が取れるログが好まれる傾向がある。例えば get rid of とか2件しか使われておらず、圧倒的に remove である。
一方で、シンプルな単語だけど開始単語としては使われないものもある。例えば次のような単語である。Expand(9)、Extend(8)、Print(5)、Optimize(5)、Publish(4)、Append(4)、Modify(3)、Manage(2)、Revise(2)、Dump(2)、Insert(2)、Migrate(2)、Enhance(1)、Edit(1) 。いずれもカッコ内は8540件に対する冒頭での登場回数である。結局、より一般的で平易な単語で表せたり、Refactor同様に抽象度が高すぎると使われないのだろう。
8000件もログを見たおかげで、迷いなくコミットメッセージが思いつくようになったのが個人的には今回書いてて最大の収穫だった。たぶんカンニングペーパーを作る行為それ自体が効率のいい学習になるという話と同じだと思う。
このまとめも100以上用例を転載してあるので、それを読むだけでも多少は効果があるんじゃないかと思う。同じようにコミットログ書きたくねぇなぁ英語わっかんねぇなぁと思っている人にとって、何か役に立つところがあれば幸いである。
ホッテントリメーカーで作るような煽りタイトルって、みなさんもう見飽きてると思うんですよね。
今調べたらホッテントリメーカー2008年だそうで。どうりでねー。古臭いなーと思いましたよー。
「一から学ぶJava」ってのをね、1.0にするだけでこんなに素敵なタイトルになるんだから面白いですねー。
タイトルを思いついただけだったんですけど、思いついたらやっぱりちゃんと中身も書かないと行けないじゃないですか。やだー
面倒くさいんですけどね。ちょっと1.0から学んでみましょうか。
Javaの1.0がリリースされたのは1996年1月23日ですね。発表されたのが1995年5月23日でJavaの誕生日といった場合にどちらを取るかで揉めることがあります。
かれこれ20年前なわけで、当時のパソコンというとハードウェアはCPU が Pentium 133MHz メモリ16M とかそんな感じだったかなあ。今どきの携帯電話の例としてiPhone 6sを挙げるとCPUが1.85GHz メモリ 2G ってんだから凄いですね。OSは1995年11月23日にリリースされたWindows95とかそんな時代背景です。インターネットがようやく一般に普及し始めたところでしょうか。
今から思うと相当弱いハードウェアですけども、そろそろVM方式を採用しても良さそうな、そんな時代でした。インタープリタだと流石に遅い、でもC言語のようなコンパイル言語だと"Write once, run anywhere"とはいかない、という判断もあったのだろうと思います。Javaが純粋なオブジェクト指向言語ではなくintなどのプリミティブ型を持つというのは、当時のマシンスペックを考えた場合、ある程度妥当な判断だったと言えるでしょう。これが後々苦しくなってくるわけなのですが。
Javaを作った会社はSun Microsystems(サン・マイクロシステムズ)というアメリカの会社で、2010年1月27日にオラクルにより吸収合併され今はありません。SolarisというOSとSPARCプロセッサでUNIXサーバーの販売で90年代後半までは一人勝ちのような状況だったと聞きます。当時にすでに「ネットワークこそがコンピュータ」(The Network is the Computer)というモットーを掲げてたんだからおかしい。1996年リリースのJavaが標準でネットワーク機能を備えていたのもこのあたりの思想から来ているのかもしれませんね。
当時のプログラミング言語としてC++が挙げられますが、C++でのプログラマへの負担といいますか、ヒューマンエラーの起きやすさといいますか、その辺を改善する目的で開発されたのがJavaだったわけです。
1996年の時点にこんな言語が登場したのですから革新的でした。
いろんな企業がJavaに賛同します。その中にはMicrosoftもありました。この時期、Microsoftは次期のWindows開発用のプラットフォームにJavaを据えようと考えていました。その後、袂を分かつことになるのですが……。
プログラム言語として構文などを見ると、C++を強く意識した構文なのは間違いなく、しかしポインタ演算を廃してポインタを機能を限定した「参照」に置き換えるなど簡素化が多く見られます。C++からはいろんな機能が削られています。関数ポインタ、構造体、演算子オーバーロード、テンプレート((テンプレートについては実装が間に合わなかったという話を聞きます))などなど。そのためC++の劣化であるように揶揄する人もいますが、こうしたものを捨てて言語仕様を比較的小さくシンプルに抑えた点は評価に値すると思います。しかし、今でもこうした削減された機能を愛する人からはJavaを腐す要素として挙げられてしまうのでした。
Wikipediaからピックアップすると1.1での大きな機能追加は
といったところです。当初よりJavaの内部文字コードはUnicodeで文字を表すchar型は16bitで設計されていました。Unicodeは当時それほど普及しておらず、Unicode対応のテキストエディタさえ少なかったと記憶しています。時代を先取りしていると言えますが、大きな誤算はUnicodeが当初16bitのコードポイントに世界のあらゆる文字を格納しようとしていたことで、漢字圏の我々からすると16bit=65,536程度の空間に文字が全部入るわけないだろ!というものだったが故に早々に破綻し、Unicodeは21bitのコードポイントに拡張されることになるのです。これはまた後の話。
なんにせよ、日本語が対応されたのは1.1からで、日本でのJavaの採用が始まったのはこの頃からと言えましょう。
当時のJavaのGUIはAWTというものでしたが、これを用いたGUIの開発は当時は結構行われていたイメージですね。Visual BASIC でGUIを作るプロダクトも結構あったと思います。GUIのためのオブジェクト指向言語としてJavaが使われていたイメージがありますね。JavaBeansもそのための仕様でした。件のsetter/getterの話題に繋がっていくのですが。
JDBCはJavaとデータベースをつなぐインターフェースです。RMIではあるJava VMから別のJava VMにオブジェクトを送って実行する、といったことができます。こうした機能が用意されたことで、ソフトウェアのフロントとしてのGUI、裏方の実装のためのネットワーク機能、データベース機能、さらにはソフトウェアを配布するためのJava Appletという布陣でJavaでのソフトウェア開発が加速していた時代といえます。
Microsoft Visual J++ もこの時代ですよ。
Java 1.1以降のバージョンのものは互換性確認のためにOracle Java Archiveからダウンロードすることができ、今でも入手することができます。もちろん、Java7ですら2015年4月にEOL(End of Life,サポート終了)となっているので、通常利用するのはJava8としてください(本稿執筆時点)。
当時のドキュメントを見るのも一興です。現在と比べると標準APIがかなり小さい。なお、当時のjavadocは今とはデザインが大きく異なります。
この時代であれば、全パッケージを舐めて標準APIを学ぶこともそう難しくはありませんでした。この時代から触っている人間は新バージョンが出るたびに増えるAPIを順に学んでいけたのです。しかし、現代にJavaを学ぶ場合、どのバージョンでは何があって……というのをいちいち学ぶ必要はほぼありません。Java5以前は一緒くたでいいと思いますし、一部のAPIで歴史的経緯があってねーというのを知っていればおそらく十分ではないでしょうか。
strictfpキーワードは浮動小数点演算をやる人は覚えておきましょう。JavaはパフォーマンスのためにCPUの浮動小数点演算を扱うことが許されており、そのため実行するCPUによって精度が異なることがあるんですね。まあ今時のCPUだと大丈夫だとは思うんですが。
リフレクション機能ではJavaのクラスを抽象的に扱うことができます。設定ファイルに書かれたクラス名のclassをロードして実行する……みたいなことができるんですね。フレームワーク的なものを作る場合には多用することになります。
1.2からは新しいGUIのSwingが採用されました。AWTがOSごとのGUIパーツを用いていたためデザインに違いがあったのに対し、Swingでは統一的なルック・アンド・フィールが用いられるようになりました。まぁ今ならJavaFXを使うのが良いと思います。
初期のJavaはやはりVM方式の実行速度の遅さが指摘されていました。実行時の構文解析を伴わないだけインタープリタよりは早いものの、実行バイナリを作るC/C++よりは遅い、そうした評価です。ここではサン・マイクロシステムズのVMにJIT(ジャストインタイムコンパイラ)が乗ったことが挙げられていますが、JIT自体は別の会社が先駆けて開発していたことは記しておきたいと思います。
JITコンパイラは実行時にJavaのバイトコードを環境のネイティブコードにコンパイルして動かす技術です。この後、JITコンパイラ、動的再コンパイル技術、世代別ガベージコレクションを備えたHotspotといった様にJavaVMは進化していきます。現代では実行時の最適化が進み、大きなスケールで見た場合、Javaの実行速度はC/C++での実装と比べてそれほど遅れるものではありません。遅くても倍の時間は掛からない程度といったところでしょうか。
あとは特記すべきはコレクションフレームワークです。皆が多用しているであろうjava.util.Listやjava.util.Mapといったライブラリが整備されたのがこの時なのです。それ以前はjava.util.Vectorやjava.util.Hachtableというクラスが可変長配列の機能を一手に担っていました。今ではVectorやHashtableは使うべきではありません。
Java の開発はSun Microsystems が主導していたけども、すべてがSunのものだったというわけでもなく。Javaには多くの会社が出資していてその中のひとつがMicrosoftだったわけですね。
Microsoft の Visual J++ では delegate とか独自機能拡張もありましたけど、裁判で問題になったのは J++ でコンパイルしたclassファイルはMicrosoftのVMでしか動かないという部分ですね(他社製のVMで動くclassファイルを作ることもできる)。classファイルがどこのVMでも動くの大事だろ、"Write once, run anywhere"だろ、お前何してくれてんの!と喧嘩になったわけです。当時のMicrosoftはブラウザまわりでも独自拡張がやりたい放題、標準規格?なにそれ美味しいの?みたいなスタンスをあちこちで見せていたものです。
結局、この事件でMicrosoftのJavaはバージョン1.1相当でストップ。好き勝手にやれないなら独自に言語作るわーとばかりに.NET フレームワークと C# といった方向に舵を取ります。
JavaがPC上でのUI開発の主力になろうとした勢いはここで潰えます。
Java SE とは別にこの時代に Java EEがリリースされていることは特記しておきたいですね。これ以後、それまでのCGIに取って代わって、JavaはWebサービスの開発のプラットフォームとして多用されるようになります。
2000年あたりからはJavaはGUI開発というよりは、Webサービスの開発が主流という流れになっていきます。インターネットのサービスが非常に発達していった時代、背後ではとてつもない量のJavaのプログラムが支えていたわけです。ただまあ、こうした産業利用は一般的なユーザーの目にはあまり入らないわけです。一般人からすればJavaといえばJava Appletみたいなイメージはずっと残っていたでしょうが、実体としてはJavaといえばServletという時代になっていたわけです。
企業で用いられる社内システムにもServletは多く採用されました。
理由はいろいろ挙げれると思うのですが
というのが大きな理由だろうと思います。JSPというテンプレートエンジンを用いてHTMLを整形してWebページを作り出す、というアーキテクチャはある意味では便利で簡単でした。
もっともHTMLの表現力に足を引きずられるため、GUIの機能性という点では後退したわけなのですが。それでもメリットが大きいと判断されたのでしょう。というか、まともにGUIを組めるプログラマがほとんどいないから、GUIのシステム開発がなかなか成功しないってのもあったんでしょうけどね。
2000年あたりというと携帯電話の普及も取り上げなければなりません。現代のスマホ、ガラケーに比べれば非常に機能は貧弱で、まさに携帯「電話」でした。要するに電話とメールぐらいしかできなかったんですね。
そこにdocomoのiアプリ、Jフォン(ボーダフォンを経て現ソフトバンク)のJavaアプリ、auのEZアプリという携帯電話上でちょっとしたアプリが動くよ!というのが乗るようになってきたんです。これがJavaを組込み用途にコンパクトにしたJava MEというものが土台となっていて(正確にはiアプリはちょっと違う)Servletと並ぶJava言語の大きなもうひとつの領域となっていました。
iアプリは当初は容量が10k byteまでといった制約があり、容量制限が非常に厳しかったのですが、新機種が出るたびに容量は緩和されていきました。
docomoはiアプリ含めiモードによって一世を風靡します。こうした土台を作ると、その上で商売をしたい人がたくさんやってきて、勝手にコンテンツを作ってくれる。docomoはそれらから手数料を取るので労せずして大金を稼げるというわけです。賭場の胴元というわけです。
この賭場が、将来にAppleのiPhone, GoogleのAndroidに荒らされることになります。docomoがなかなかiPhoneを出さなかったのもiモードという自前の賭場を失うことを良しとしなかったためです。金づるを失ったdocomoはSamsungと組んで独自の携帯向けOSであるTizenの開発に乗り出します。そんなTizenですが鳴かず飛ばず。噂ではインドあたりではリリースされたとか、なんとか。
話を2001年に戻しましょう。
Microsoft離反でGUIのプラットフォームとしてのJavaというものは存在感を弱めていました。この分野の復権に寄与したのはJava 1.4 (2002年2月6日)で導入されたJava Web Startです。
Java Appletがブラウザ埋め込みで動作したのに対し、Java Web Startではブラウザから起動しつつも独立したアプリとして起動するのです。
Webシステムが企業の社内システムに採用された話は先に述べたとおりですが、やはりWebシステムのGUIというのはHTMLに引きずられて貧弱だったんですね。
端的に言えば入力値が数字かどうか?みたいなチェックがなかなか難しい。HTML上でJavaScriptでやるわけなんですが、なかなか気持よく入力できるような感じにはならなかったんですね。
また、Ajaxによるブラウザのページ遷移を伴わない通信というのが出てきたのも2005年ぐらいなので、入力値に対してサーバ問い合わせするようなことはできなかった。当時だと一旦画面遷移させないとできなかったわけです。
こうした事情から、クライアントサイド、要するにPC側でもっとリッチなUIが使いたい!という要望があったわけです。Webシステム使いにくい!という不満の噴出と言ってもいい。そこで出てきたのがRIA (Rich Internet Applications)というわけです。
Javaは1.0時代のAppletからそうですが、ネットワークを介して別のPCにプログラムを送り込み、そこで動作させるという能力を持っていました。それこそまさにRIAに求められる機能性だったわけですね。
RIAの代表とされるのは
あたりです。三つ巴の戦い、どこに軍配が上がるのか!?と注目されましたが、勝利したのはHTML / JavaScriptでした。
Google MAP で注目を浴びたAjax技術、それまでブラウザでは不可能と思われていた高級なGUIをHTML / JavaScriptで実現させました。もうやめて欲しいですよね。せっかく脱ブラウザの流れが来たと思ったのにまたWebシステムに逆戻りですよ。
RIAが失速した理由として考慮して置かなければいけないのはスマートフォンの台頭です。RIAでは端末を選ばずどこでも同じアプリが動かせる点がポイントのひとつでしたが、スマートフォンではそうは行かない。"Write once, run anywhere"を破壊したのはスマートフォンだったというわけです。
しかし、先日インストールなしでアプリを実行するAndroid Instant Appsが発表されたりしまして、結局RIAの思想といいますか、要求というのは今でも息づいているのだなと思った次第です。
1.3 / 1.4 では機能追加はあっても言語構文が大きく変わることはありませんでした。大きく変わったのはJava 5です。この時からバージョニングが変わって1.5ではなく5と表記されるようになりました。
Java5の特徴はなんといってもジェネリクス。それまでjava.util.Listにデータを出し入れするのにはキャストが必須だったわけですが、ようやくキャストから開放され型の安全度がぐっと高まりました。その他に以下のような変更があります。
言語としては随分変わっったわけですが、もうかれこれ10年以上前のことですからこれらの機能が「Java5から導入された」という知識は今となってはあまり必要とされません。これらの機能が使えないJava 1.4で開発をする事案が殆ど無いからです。0ではないのが悲しいところではありますが。
Java 6 (2006年12月11日)がリリースされた後、Java 7 (2011年7月28日) が出るまでJavaは停滞してしまいます。その間にSun Microsystemsという会社がなくなってしまったためです。
Sun Microsystems の経営状況が悪化しており、ついに身売りをすることになりました。身売り先はIBMともGoogleとも噂されましたが結局2010年1月27日にオラクルに吸収合併されました。
Javaの停滞中にはJava VM上で動く非Java言語も台頭してきました。Scalaなどですね。
やや戻って2007年にAndroidが発表されます。Androidの開発言語にはJavaが採用されていますが、実行環境はJava VMではなく、ライセンス的な事情でJava(TM)は名乗らない微妙な位置関係にあります。
Java 5 以降で大きく言語仕様に手が入るのは Java 8 (2014年3月18日)です。並列処理を行うためのStream APIと、そのために簡易に関数を定義するためのラムダ式が導入された点が大きいですね。日付APIも刷新されました。
このように、Javaは1.1の黄金時代から今に至るまで利用ジャンルを転戦しながら産業の土台となって支えてきた歴史があります。ジャンルの趨勢により浮き沈みもあります。今後についても決して楽観視はできないでしょう。Javaを学ぶことはプログラミングを学ぶステップとしては意義はあると思いますが、Javaを学べばゴールというわけではありません。プログラム言語も次世代へと移りつつあります。業界動向には注視していきましょう。
HEAD ~1
HEADの親
HEAD ~2
HEADの親の親
HEAD ^1
HEADの1番目の親
HEAD ^2
HEADの2番目の親
HEAD
ORIG_HEAD
git merge や git reset でHEADが移動してしまう.
ORIG_HEADを使うことで移動前のHEADを指定できる.
FETCH_HEAD
git fetch によってリモートリポジトリから取得した最新のコミットを指定できる.
git log --oneline
logを一行で表示する.
git log --decorate
git log --follow FILENAME
FILENAMEのファイルの変更履歴を,たとえ途中でリネームされたとしてもそれも見る.
git log --author <name>
git log --graph
git log -p
git diff <base commit>...<opposit commit>
git log -S "string"
git bisect start <bug commit> <correct commit>
二分探索の開始
git bisect good
git bisect bad
git bisect reset
二分探索の終了
git checkout <branch name, needs to be rebased> git rebase <base of rebase>
rebase
git pull --rebase
git pull は git fetch + git merge
merge ではなく rebase したい場合に利用するのがよい.
git log --merge
git stash
内容の退避
git stash pop
退避した内容の復活
git stash list
退避した内容の一覧
git worktree
git submodule
git rebase -i HEAD~N
Nは自然数.
編集時にエディタが開くが,編集を終えてエディタを閉じてもrebaseが機能しないことがある.
その場合は次のように, .gitconfig へエディタのパスを書けばよい.
[core] editor = /usr/bin/vim
あこがれの英字キーボードを手に入れたから早速会社のパソコンに接続してみた。会社のパソコンは Windows 7。解像度もメモリも CPU も悲劇的な支給パソコンをなんとか使えるレベルで動かしてくれる頼もしいやつ。
「カシュカシュカシュ」
う〜ん、シングルクォーテーションとダブルクォーテーションがうちやすい! あとアットマークをシフトを押しながら入力するのは新鮮かな。
「コトコトコト」
スペースキーが広い! 打ちやすい! ついつい連打しちゃう。キー配列になれるのは時間がかかりそうだけどハッカーみたいでかっこいい。だけどちょっと、ううん、かなりストレスフルなことが一点あって、日本語を入力しようとしたらキー配列がJIS配列になっちゃうんだ。いちおう英字配列にはキーコンビネーションで切り替えられるんだけど、キートップの印字とちがうじゃない。ほら '*' が '(' だったりさ。
今思えば英語入力にわりきって使えば良かったって思うよ。でも往々にしてわりきるのって無理でしょ。
こまったときのグーグル頼み。グーグルさんに日本語キーボードのパソコンで外付け英字キーボードを上手く使う方法はないのって聞いてみた。そうしたらいろいろおすすめしてくれたから、まあ、このくらいの苦労はしないと英字キーボードを買った意味はないよねって、というかこっちから苦労を買ってやろうって、ふふんと思いながらいろんなページを確認したの。業務中だったけど。
それで、レジストリを書き換えてやればいいって書いてあるページを見つけた(http://blog.heiichi.com/?eid=792239)。書き換えるのは
パス : HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/i8042prt/Parameters キー : LayerDriver JPN, OverrideKeyboardIdentifier, OverrideKeyboardSubtype
か。でもレジストリエディタってなんか使いづらいし、怖いなあ。おっとそういえば業務のデファクトスタンダードアプリ Excel で、拡張コンテキストメニューから「読み込み専用で開く」ためにレジストリを書き換える PowerShell スクリプトを作ったんだっけ。マイクロソフトオフィスがアップデートするたびにレジストリ書き換えられるもんだから、あたまにきて作ったんだっけ……。
New-ItemProperty -Force -Path 'Registry::HKEY_CLASSES_ROOT/Excel.Sheet.12/shell/OpenAsReadOnly' -Name ddeexec -PropertyType String -Value "[open("%1",,1,,,,,,,,,,,,1,,1)]"
よっし、エンジニアならコンポーネントの再利用だな、ってスクリプトをコピーしてぺたぺた(スクリプトは超危険なので割愛!)。パスをかえて、値はこれで、そうそう現在の設定を確認して英字配列と日本語配列を自動で切り替えるようにしたいな、むふふ、なんてつなげたばかりの英字キーボードですくりぷとすくりぷと書いていたの。
そんで実行。エラーか。ふむふむああええおお、パスまちがえちゃった。
こんどこそ実行。エラーなく終わって、ちゃんとキーの名前と値が入っている。さてさてそれでは再起動しましょう。
「ブイーン」
これ面倒なんだよなー。ハードディスクの暗号化解除っと。あれ、起動画面に移らないなあ。メモリチェックが走っているのか。ふーん。
……おわらないんだけど………………………………………………。おそるおそる画面をみたら、
「Windowsが起動できませんでした。システム管理者に連絡してください。」
うっわーーー。ブルースクリーンだーーー。はじめて見たーーー。本当にブルースクリーンででるんだなあ。
正直このときはラピュタをみつけたパズーの気分だったかも。ぼくの場合はこの先にはわくわくなんてなかったけどさ。だんだん、やべー、これやべー、これやべーや、これすごくやばいよね、って正気にもどった。そんで隣のお仲間にバレる前に強制終了。ふう。多分再起動中だっておもってくれたよね。
だいじょうぶだ Windows は軍用にも使われる堅牢性の高い OS だ。これくらいのエラーは普通再起動したらいつもと同じように退屈な起動プロンプトがでるはず。そうやって自分をまず信じる。それが一番大事。
まずは軽い深呼吸。そして電源オン。
「ブイーン」
ハードディスクの暗号化解除は BIOS レベルだから変わらないのか。Windows は予期されない終了をしたって? そのとおり! 気にせずに君はいつものように平常心で起動してくれたまえ。
あかんわ。これ完全にあかんわ。二回起動して二回だめって、これなんかいやってもダメなパターンはいったよね。エンジニアのはしっくれだけどそれくらいはわかる。
とりあえず電源を落として、気持ちを落ち着かせるために散歩しよう。ああ、今日は雲がきれいだなあ。風もふいていてはるだなあ。どうしよ。ぼくも答えはわかっていたんだけどね。管理部にごめなさいしてリカバリ DVD をかりてくればいいんだよね。でもさ、ただの箱になったパソコンはお客様のものっていう派遣の立場だしさ、絶対に原因追求でレジストリいじったことを告白させられるしさ、ああなんか春と秋ってにてるよね。
あとさブルースクリーンになった原因もわかったの。ふいにあああれだなって思い浮かんだんだけどさ、スクリプトつかいまわしちゃったせいで OverrideKeyboardSubtype キーの型を DWORD じゃなくて String にしてたのよ。ぜったいにこれで起動シーケンスで致命的エラーはいてんだろうなって。
そんな風に思いながら、自席に戻って、もう一回電源起動。もう一回よく画面を確認する。……むむ自動修復だと。よかろう最後の望みだ。かなえてやろうじゃないか。へー最後に記録した正常状態にシステムを復元するのか。なんか説明書きに「最近インストールしたプログラムとか消えるかもね。ハハッ。」て書いてあるけど、しばらくインストールなんてしていないし、初期状態に戻んなかったらまあいいよって感じ。ポチッとな。
そんでもって三十分から一時間経ったかなあ。あまりにも時間がかかるからトイレの個室で頭をかかえてたの。自席に戻るとパソコンの電源が落ちているわけ。さてとこれはラストチャンスだ。なんのチャンスかわかんないけどラストであることはあきらかだよね。そして電源をいれた。
この時ばかりは神様に祈ったね。だって計算機はプログラムしたようにしか動かないから、お祈りなんてしても意味ないもんね。だから神様にお祈りしたの、どうかおねがいします、今後はこれにこりてレジストリなんてぜったいにいじりませんので、この計算機が正しく動くことを祈ってくださいって。
結局、無事復旧できた。なにひとつ異常なく Windows 7 は立ち上がって来て、みなれた壁紙がでてきた。おそるおそるレジストリを確認したら、ちゃんとぼくがいじくるまえにもどっていた。ありがとう Windows! ありがとう自動修復機能! いちおうありがとう神様!
それでも外付け英字キーボードで日本語入力したいんだーて人はここらへんを見たら幸せになれるよ。
USB英語キーボード付けた。(英語、日本語キーボードの共存、KeyboardTypeOverride) 202122 (http://202122.iku4.com/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3/%EF%BD%95%EF%BD%93%EF%BD%82%E8%8B%B1%E8%AA%9E%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E4%BB%98%E3%81%91%E3%81%9F%E3%80%82%EF%BC%88%E8%8B%B1%E8%AA%9E%E3%80%81%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89)
USBポートに対しての設定だからブートで失敗することはないと思うよ(ブルースクリーンを発生させたもののことば)。
いちおうこれを書くにあたって、自宅のパソコン Windows Vista で再現できないかためしてみた。検証内容は以下の二つ。
結論としては両方とも大成功! ちゃんとレジストリエディタから編集したら、英字キーボードで日本語入力が快適にできるようになったし、 DWORD を String に変更したらブルースクリーンがでるようになったし! Vista だと会社の Windows 7 ではできた自動修復ができないし! なんかブートセクションとデータセクションが分けられるようになったのって Windows 7 かららしいし!
だけどここは会社じゃなくて自宅だから、メイン OS の Ubuntu で Windows 領域をマウントして華麗に chntpw を叩いてレジストリを修復できる。そう Linux ならね。
:echo 1 / 0 :echo 0 / 0
2147483647 -2147483648
きっしょwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
他の言語もチェックしてみるか
package main import "fmt" func main() { fmt.Println(1 / 0) fmt.Println(0 / 0) }
echo 1 / 0; echo 0 / 0;
PHP Warning: Division by zero。
print 1 / 0 print 0 / 0
ZeroDivisionError: integer division or modulo by zero
print(1 / 0) print(0 / 0)
ZeroDivisionError: division by zero
nodejsだと1/0と0/0で異なるメッセージが表示された。
console.log(1 / 0);
Infinity
console.log(0 / 0);
luajitだとnodejsで表示されたメッセージの短縮形で表示された
print(1 / 0)
print(0 / 0)
main = do print(1 / 0)
Infinity
main = do print(0 / 0)
public class Test { public static void main(String[] args) { System.out.println(1 / 0); } }
public class Test { public static void main(String[] args) { System.out.println(0 / 0); } }
Exception in thread "main" java.lang.ArithmeticException: / by zero at Test.main(Test.java:3)
#!/bin/bash echo $((1 / 0)) echo $((0 / 0))
test.bash: 行 4: 1 / 0: 0 による除算です (エラーのあるトークンは "0") test.bash: 行 5: 0 / 0: 0 による除算です (エラーのあるトークンは "0")
haskellとnodejsとluajitはエラーにならないけどまあいい。
Vimはやべえよ。
デカルト閉圏というものがある。これは型付きλ計算や直観主義論理のモデルとなる圏だけども、その特徴は
である。これらをプログラムに対応させると次のようになるだろう。
終対象 | unit |
直積 | 直積型 |
冪 | 関数の型 |
- | 双対概念 | プログラムへの対応 |
終対象 | 始対象 | 終了しない計算(例外) |
直積 | 直和 | 判別共用体 |
冪 | 余冪 | ??? |
余冪に対応するものがよく分からん。余冪の定義からいうと余冪を X**Y と表現することにすれば
Hom(X**Y, Z)≅Hom(X, Y⊕Z)
が成立すればよい。だから、
IntOrString = IntValue of int | StringValue of string let f(x:int) : IntOrString = if x >= 2 then IntValue(1) else StringValue("1")
let f'(xy:X**Y) : string = "1"
のように書き換えることができればそれは余冪と言えると思えるのだが、そのような書き換えは可能なのか?
とりあえずこの場合に限れば、
exception Y of int type XToYCopower(x:int) = let x' = if x >= 2 then raise(Y(1)) else x let f'(xy:XToYCopower) = "1"
みたいにして、呼び出すときは、
let mutable z: IntOrString = IntValue(0) try z <- StringValue(f'(XToYCopower(0))) with | Y(y) -> z <- IntValue(y)
とすると、書き換えができているような気もするし、やはり何か違う気もする。
よく分からんなぁ…。
var s1 = (new Func<string>(() => { var o = "Wow!"; return o; }).Invoke());
var s2 = (new Func<int, string>((f) => { return f.ToString(); }).Invoke(100));
var s3 = (new Func<int, int, string>((f, g) => { return (f + g).ToString(); }).Invoke(100, 30000));
マジレスすると、U+00a5なら使える。俺なら設計を修正させるけど。
Path.GetInvalidFileNameChars メソッド (System.IO)
using System; using System.IO; namespace TestInvalidFileName { class Program { static void Main(string[] args) { // Get a list of invalid file characters. char[] invalidFileChars = Path.GetInvalidFileNameChars(); Console.WriteLine("The following characters are invalid in a filename:"); ShowChars(invalidFileChars); Console.WriteLine(); string fileName = '\u00a5' + "108"; using (var fs = File.Create(fileName)) { if (fs != null) { Console.WriteLine("File was created:" + fileName); fs.Close(); } else { Console.WriteLine("File was not created:" + fileName); } } } public static void ShowChars(char[] charArray) { Console.WriteLine("Char\tHex Value"); // Display each invalid character to the console. Array.Sort(charArray); foreach (char someChar in charArray) { if (Char.IsWhiteSpace(someChar)) { Console.WriteLine(",\t{0:X4}", (int)someChar); } else { Console.WriteLine("{0:c},\t{1:X4}", someChar, (int)someChar); } } } } }
The following characters are invalid in a filename: Char Hex Value (中略) ", 0022 **, 002A /, 002F :, 003A >, 003C >, 003E ?, 003F \, 005C |, 007C File was created:\108
IsNumeric Function (Visual Basic)
IsNumeric returns True if the data type of Expression is Boolean, Byte, Decimal, Double, Integer, Long, SByte, Short, Single, UInteger, ULong, or UShort, or an Object that contains one of those numeric types. It also returns True if Expression is a Char or String that can be successfully converted to a number.
ここは普通のことをいっている。 IsNumeric が True を返すのは以下のとき。
Indicates that no beginning value has been assigned to a Variant variable. An Empty variable is represented as 0 in a numeric context or a zero-length string ("") in a string context.
Empty は context にあわせて以下のように解釈される。
というわけで IsNumeric(Empty) は Empty が数値として解釈されて 0 になるので True を返す。
たぶんどこにも書いてないのでメモ。
https://developers.google.com/apps-script/reference/utilities/utilities#formatDate(Date,String,String)]
timeZone のフォーマットについての言及がないが、"GMT" 以外のタイムゾーンを設定するには、たとえば +09:00 (JST) の場合、
Utilities.formatDate(new Date, 'Etc/GMT-9', "yyyy-MM-dd'T'HH:mm:ss'Z'");
public void set(String k,double d){
v.put(k,d);
}
を入れた方が美しかったな
あ、それにdistanceはDoubleを返すようにして軸を一切共有しない場合はnullにした方がよかったな
奥が深い
勉強が足りないな
class Obj{ HashMap<String,Double> v = new HashMap<>(); public double distance(Obj o){ double s = 0; for(String k:v.keySet()){ s += (o.v.containsKey(k))?(Math.pow(o.v.get(k)-v.get(k),2)):(0); } if(s == 0)return 0; return Math.sqrt(s); } } Obj p1 = new Obj(); Obj p2 = new Obj(); p1.v.put("X",1.0); p1.v.put("Y",2.0); p1.v.put("Z",3.0); p2.v.put("X",3.0); p2.v.put("Y",4.0); p2.v.put("Z",5.0); System.out.println(p1.distance(p2));
ううううつくしい!
http://individualist.link/ (←ドメインかっこいいでしょ)
〜 居酒屋にて 〜
A「やっぱり若者が稼ぐにはアプリ作るしかないと思うんですよ」
B「あー分かる」
C「ゲームは当たると大きくていいよね」
A「いいですよね」
A「そういう人の話聞いてみたいんですけどなかなか出てこないですね」
B「どういう人がどういうサービスで当てたのかまとめたい」
A「いいですねえ。Wiki 的な」
B「Google Docs とかでやってみる?」
A「おお、やりましょう」
B「Webサービスにしてもいいかも」
B「できた」
B「ドメイン取ろう」
アルコール入ってるから話のディティールうろ覚えだけどこんな流れで作りました。
当てたいなら先例を見るのが一番参考になるはずだし、僕は個人で作ったものが流行っているのを見るのが好きだし、そういうのとても興味ある。
このサイトを見ていると、どういう人がこのサービス作ったんだとか、これ個人で作ってたんだという発見があっておもしろいと思います。
1時間で出来たというのはほとんど誇張ではなくて、デザインに拘る時間とサーバーに設置する時間を抜かせば本当に1時間でできます。
・画像保存
・タグ付け
・JavaScriptで動き付ける
・CSS整える
・デザイン
というような感じになる。これらを実直にいちいち実装してたら1日で終わるか分かりません。
本を読む一番はやい方法は、文字を読まないことです。
ちょっとコードが書けると実装する道筋が思いついちゃうからライブラリを探す考えに及ばず実装しちゃう事があると思います。
そういう事は避けて、アプリを書くならアプリの本体を最小に済ませるか、ライブラリ自体を作ることに力を入れましょう。
こちらのサイトではRailsのレールに乗っかって開発しました。
以下の例はRailsを使った方法ですが、モダンなフレームワークを使っているのであればだいたい似たような話になると思う。
手に馴染んだフレームワークがあるならなんでもいい。
クソ小さなロジックと数ページしかないならPHPでもいいけど、
とにかくはやく作ることがしたいなら何かしらフレームワーク使ったほうがいい。
秘伝の Rails Application Template を用意しておくのも良い。
モダンなフレームワークなら何も考えずにデータベース接続できるはず。
Rails なら config/database.yml に接続情報書いて rake db:create && rails g model User name:string です。
ソーシャルアカウントでログインする要件が出たら、何も考えずに「あ、OmniAuth」となりましょう。
・画像保存
画像保存が必要になったら反射的に「Paperclip か CarrierWave どっにしよう」となりましょう。
・タグ付け
ActsAsTaggableOn を使います。
has_many :through のめんどくさいタグの実装ですが
これ入れて rake acts_as_taggable_on_engine:install:migrations && rake db:migrate を打てば一発で完成します。
・JavaScript で動き付ける
早くつくりたいんなら JavaScript は捨てましょう。
少なくとも生の JavaScript 書く時代ではないので CoffeeScript 使うと良いです。
・CSS 整える
とりあえず Bootstrap 入れましょう。
クラスの付け方を覚えちゃうと CSS 弄って HTML リロードして確認なんてことしなくても形は整います。
Bourbon gem 使って mixin ライブラリ組み込んじゃうのもいいですね。
HTML 書くのやめましょう。
Haml や Slim のようなテンプレートエンジンを使います。
Zen Coding でもいいけど、結局出力されるのが HTML じゃ見通し悪くて辛いと思う。
Web Components の時代になったらもっと簡単になるんだろうな。
・デザイン
ただ、Webページやアプリというのはだいたい決まったパターンがあるので、いろいろな事例を見るとよいでしょう。
正直レイアウト自体は他のサイト真似るのは悪くない判断だと思います。
むしろその方がユーザーにとって慣れ親しんだ分かりやすいサイトでもあります。
http://individualist.link/ の場合、http://www.producthunt.com/ を異常なほど参考にしました。
まあここまで書いてなんだけど、前提知識として Rails が使えるようになってないといけないのは敷居高くて悪かったと思う。
なお、今回つくったこのサイト、ぜひともみなさんにも投稿していただきたいのですが現在投稿者は承認制としております。
私本当に個人が作って運営しているというアプリやサイトというのが好きでして、
理論的
普通に使う。
何らかの挙動をモデル化して記述する際、モデル化しない(しきれない)要素はどうしても発生する。
そのような要素を考慮しないで述べる際に「理論的には○○」と言う。
例えばプログラムの実行速度をCPUクロックや命令の実行サイクル数から「理論的に」求めることはできるが、
実際には他のタスクの割り込みやメモリスワップ、温度上昇によるクロック低下などにより、実際の実行速度は理論値より低くなる。
1+1
誰が数値の加算だと言った? データ型が違えば、演算子の挙動も違うんだよ。
わたしの勘違いだったら申し訳ないけど、C#で次のようにコードを書いたら、ぬるぽ例外が発生しましたよ。
public class DoSample : System.Management.Automation.PSCmdlet
{
...
public DoSample() {
...
if ((this.MyInvocation == null) || (string.IsNullOrEmpty(this.MyInvocation.ScriptName))) {
return;
}
...
}
}
Option Explicit Private Const INTERNET_OPEN_TYPE_PRECONFIG = 0 Private Const INTERNET_OPEN_TYPE_DIRECT = 1 Private Const INTERNET_OPEN_TYPE_PROXY = 3 Private Const INTERNET_SERVICE_HTTP = 3 Private Const INTERNET_DEFAULT_HTTP_PORT = 80 Private Const INTERNET_FLAG_RELOAD = &amp;H80000000 Private Declare Function InternetOpenA Lib "wininet.dll" (ByVal sCallerName As String, ByVal dwAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal dwFlags As Long) As Long Private Declare Function InternetConnectA Lib "wininet.dll" (ByVal hInternetSession As Long, ByVal sServerName As String, ByVal nProxyPort As Integer, ByVal sUserName As String, ByVal sPassword As String, ByVal dwService As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByRef sBuffer As Byte, ByVal lNumberBytesToRead As Long, ByRef lNumberOfBytesRead As Long) As Long Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternetHandle As Long) As Long Private Declare Function HttpOpenRequestA Lib "wininet.dll" (ByVal hConnect As Long, ByVal sVerb As String, ByVal sObjectName As String, ByVal sVersion As String, ByVal sReferer As String, ByVal sAcceptTypes As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long Private Declare Function HttpSendRequestA Lib "wininet.dll" (ByVal hRequest As Long, ByVal sHeaders As String, ByVal dwHeadersLength As Long, ByVal lpOptional As String, ByVal dwOptionalLength As Long) As Long Private Function submitPost(ByRef host, ByRef url_path, ByRef sendString) As Variant Dim dataArray() As Byte, dataPosition, dataSize 'WinInet初期化 Dim hInternet hInternet = InternetOpenA(vbNullString, INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0) If hInternet = 0 Then submitPost = dataArray Exit Function End If 'サーバ接続 Dim hConnect hConnect = InternetConnectA(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, vbNullString, vbNullString, INTERNET_SERVICE_HTTP, 0, 0) If hConnect = 0 Then InternetCloseHandle hInternet submitPost = dataArray Exit Function End If 'リクエストを初期化 Dim tmpURL As String * 255 tmpURL = url_path Dim hRequest hRequest = HttpOpenRequestA(hConnect, "POST", tmpURL, "HTTP/1.1", vbNullString, 0, INTERNET_FLAG_RELOAD, 0) If hRequest = 0 Then InternetCloseHandle hConnect InternetCloseHandle hInternet submitPost = dataArray Exit Function End If 'リクエストを送信 Const strHeader = "Content-Type: application/x-www-form-urlencoded" HttpSendRequestA hRequest, strHeader, Len(strHeader), sendString, Len(sendString) 'データ取得 Dim readResult, tmpArray(1023) As Byte, tmpPosition, tmpSize dataPosition = 0 dataSize = 0 Do tmpSize = 0 Erase tmpArray readResult = InternetReadFile(hRequest, tmpArray(0), 1024, tmpSize) If Not readResult = 1 Or tmpSize = 0 Then Exit Do End If dataSize = dataSize + tmpSize ReDim Preserve dataArray(dataSize - 1) For tmpPosition = 0 To tmpSize - 1 Step 1 dataArray(dataPosition) = tmpArray(tmpPosition) dataPosition = dataPosition + 1 Next Loop 'クローズ処理 InternetCloseHandle hRequest InternetCloseHandle hConnect InternetCloseHandle hInternet submitPost = dataArray End Function Public Function downloadFilePost(ByRef targetURL, ByVal sendArray, ByRef savePath) As Boolean 'URLの分解 Dim startE, endE, host, url_path startE = InStr(1, targetURL, "//") + 2 endE = InStr(startE, targetURL, "/") endE = IIf(startE > endE, Len(targetURL) + 1, endE) host = Mid(targetURL, startE, endE - startE) url_path = Mid(targetURL, endE) 'ポストデータのエンコード Dim jscript With CreateObject("ScriptControl") .Language = "JScript" Set jscript = .CodeObject End With Dim ix, sendBuffer For ix = 0 To UBound(sendArray) Step 1 sendBuffer = Split(sendArray(ix), "=") sendArray(ix) = sendBuffer(0) &amp; "=" &amp; jscript.encodeURIComponent(sendBuffer(1)) Next Set jscript = Nothing Dim data data = submitPost(host, url_path, Join(sendArray, "&amp;")) If LenB(data) <= 0 Then downloadFilePost = False Exit Function End If 'バイナリで書き込み With CreateObject("ADODB.Stream") .Type = 1 .Open .Write data .SaveToFile savePath, 2 .Close End With downloadFilePost = True End Function
Androidアプリ作ろうとしてJavaプログラマ募集したらクズしかこなかった全部クズだったとか、ひどくありません?
まあそれは置いといて、UIみたいに最初から仕様を決められなくて何度も作り直すようなコードはJavaは不向きみたいな話もまったく同意できないわ。
string url = "http://www…";
のように、URLを文字列で持っていたけど、やっぱアドレス用のクラスでもったほうが安心だなって思って
URI url = new URI("http://www…");
と書き直しました。
当然、このurlを参照しているところは全部エラーになります。
Javaをはじめとする静的型の言語をけなしてる人たちは、これが面倒だと思うんでしょうか。
逆にエラーの出ている箇所を片っ端から直してエラーが無くなれば、修正漏れなしの証拠だからめちゃくちゃ安心できます。
JavascriptやらRubyでこういうことをしたら、人間が目を皿のようにして全部チェックしないといけないわけでしょ。
どう考えても変更の多いコードこそ動的型の言語は不向きだと思われますが。
こういう話をすると、エディタの検索でどうこうって反論がくると思いますけど、あれは言語を理解しないでテキストでマッチしてるだけでしょ。
たとえば func($url); と他のサブルーチンに渡して、
function func($address) {} みたいに受け取って、そこから先は文字列として扱ってるコードがあっても探しきれませんよね。
静的型の言語なら、void func(string address) {} を void func(URI address) {}と修正したら修正漏れの箇所があってもエラーが伝播して言って、すぐ分かります。
OracleとGoogleの裁判がらみで「Java終了よかったよかった」みたいな話の流れで、AndroidアプリはJavascriptで作ればいいって盛り上がってたけど、そうなったらIDEのサポートが大幅になくなる原始的な環境に逆戻りでしょ。
勘弁して欲しい。
ほんとうに動的型の言語はめんどくさい。