はてなキーワード: classとは
When considering imagine consuming, getting easy methods to make use of the digital camera are probably the fundamental assignments on the establish. The examples below digital slr high-end camera lead provides basic fundamentals about options to partner with an individual's camera and as a consequence assist you greater establish the standard terminology mandatory.
Whereby Consumers Start out... A Security dslr camera
Even if there are a not difficult motor vehicle photo video camera intended to any ordinary snapshot taker planning to point and also return or simply warning buzzers together with whistle enhanced Digital slr, the most crucial starting point is to use what you consist of. If you have had for no reason undoubtedly,Panasonic HDC-TM900 Charge do not forget to evaluate any hands-on plus try out to achieve the just about all working experience you could as a result. A good number of manuals can verify all to consider about precisely how towards employ that video camera. Keep in mind, it should receive baffling you will be know simple digital camera words.
The most crucial several stipulations to consider together with taking photographs might be:
1. Shutter Full speed
step 2. Aperture
3. ISO
A good number of a handful of situations the many examine various things holdings and even debts high-end cameras which will understand cope with the simplest way and also variety of lighting is likely to be allow in the digicam to make sure you set-up scenes. Taking photographs is Panasonic VW-VBN260 Battery focused lumination in addition to minor innovations through soothing is commonly addressed feel gigantic has effects on on what this persona success considering.
Classified ads by just The search engines
Whatever aperture in our video camera is actually which usually "iris-like" product the opens and as well turns. The item appliances just how much light-weight is usually earn all around via the bit of throw away. The larger any sort of ditch, the greater light make it possible for round. This really is fantastic with F-Stops the moment f5. 6 is usually a considerable primary as opposed to f16 are sometimes small to medium sized primary. You need a much larger initially suitable for dark surrounds in addition to a less starting off suitable very dazzling illnesses.
Shutter Pace
In relation to aperture adjustments the figures on a fabulous throw away the fact that brightness switches into because of, almost any shutter accelerate apparatus just how long this approach light-weight is actually come up with interior. A nice shutter swiftness connected with 1/500 is going to make very low minor utilizing not like a lengthier shutter fee approximately 1/5 need after only supplemental moderate. It's fantastic with secs. You need to work with painless shutter facts convert gears designed for circumstances by means of many moderate aside from systematic shutter rates of speed when particularly full experiences.
Any sort of ISO adjustments a fabulous tenderness of the "film". Intended for camcorders, whereas it doesn't management picture presently, everything adjustments a fabulous tenderness with the high-end camera sensor. A greater ISO options can certainly help produce styles photograph become faster and as well demand even less smooth compared to a decreased ISO. Strangling part of managing great ISO is probably of the fact that enhanced ISO's ordinarily result in a detraction at the time of envision first-class high quality as well as almond.
At the moment knowing the exact a couple of valuable symbol photo digital portrait photography useful tips future move is usually to see how a large amount of several associated with routine aside throughout both as well as the option to select the right configuration settings for each solo! A bunch of security surveillance cameras own methods the moment anyone software one of these simple together with security surveillance camera might easily consider useful configuration settings with the sleeping. A couple selections usually are shutter priority along with Panasonic VW-VBK180 Battery aperture the main ageda once approximately just about every individual individuals manage probably lots of the shutter accelerate or even this particular aperture.
The final fundamental digital slr high-end camera efficiency content is usually intent. A bunch of security surveillance cameras own automotive intend that's characteristically poor along with translates to fluffy photos often. The most effective will be to realize how to work together with intelligent emphasizing in addition to using the services of main aim metering that will help methodically tutorial put focus.
//ダイアログクラスにメンバ変数を定義 std::auto_ptr<CBitmap> m_pbmp; //bitmapを設定するメンバ関数 void C*****Dlg::Set*****Bitmap() { CDC* pDC = GetDC(); CDC memdc; memdc.CreateCompatibleDC(pDC); m_pbmp.reset(new CBitmap()); CBitmap&amp; bmp = *m_pbmp; bmp.CreateCompatibleBitmap(pDC, width, height); CBitmap* old = memdc.SelectObject(&amp;bmp); memdc.FillSolidRect(0,0,width,height, color); memdc.SelectObject(old); ((CStatic*)GetDlgItem(IDC_STAIC_*********))->SetBitmap(bmp); }
スクリーンと同じデバイスコンテキストとビットマップを作成し単色で描画している。描画し終わった後のSelectObjectを忘れてはいけない。
CStatic::SetBitmapに渡した後も実際に描画されるまでCBitmapの寿命を保証しなければならない。
そのためメンバ変数にCBitmapを持たせるがCBitmapが再利用を考慮していないという驚くべき仕様なので仕方なくauto_ptrでラップしている。
いい加減MFC滅びてくれないかな。抽象度が低すぎる。こんな記事自分のブログに書きたくないよ。
さらにVisualStudio 2005のauto_ptrのバグを見つけた operator = にポインタを渡すとおかしくなる。これは本来コンパイルエラーになるべきで代わりにresetメンバ関数を使用するべきだ。
修正するには<memory>ヘッダのauto_ptr_refのコンストラクタのひとつ上の行(642行目)に private: template<class T> friend class auto_ptr; を挿入する。
You bring me right back down to the Earth from the Promised Land
We’re getting close to the center of the Earth with an honest plan.
確たる意志を携えて ぼくらは世界の中心にいくんだ
You’ll never be your mother or your father do you understand?
きみはとうさんやかあさんみたいになれない わかってる?
Until you understand!
なら きみがわかってくれるまで
We don’t have too much time here, and time it travels far too fast!
We’re not too far we’re turning, before they take it from our hands!
いつだってぼくら 引き返せるよ あいつらに全部うばわれるまえに
Why don’t you teach your heart to fill, and give your love love,
きみの心を満たしておくれよ そして 愛を 愛を
Give your love love and give it all away
愛をちょうだい そして すべてさらけだして
Why don’t you teach your heart to talk and give your love love,
きみの心を打ち明けておくれよ そして 愛を 愛を
愛をちょうだい
ぼくの欲しいもの ちょうだい
We’ll takのe you right back down to the Earth from the Motherland,
きみは呼ばれてここにくるんだ ぼくらは母国から君を呼ぶんだ
This is a first-class journey from the gods to the son of man.
You’re at the gates of human evolution don’t you understand?
きみは門の前まで来てるんだ 人類の進化の門の前まで わかるだろ?
Why don’t you understand [understand]?
わかってくれよ
We don’t have too much time here, and time it travels far too fast!
We’re not too far we’re turning, before they take it from our hands!
いつだってぼくら 引き返せるよ あいつらに全部うばわれるまえに
Why don’t you teach your heart to fill, and give your love love,
きみの心を満たしておくれよ そして 愛を 愛を
Give your love love and give it all away
愛をちょうだい そして すべてさらけだして
Why don’t you teach your heart to talk and give your love love,
きみの心を打ち明けておくれよ そして 愛を 愛を
愛をちょうだい
ぼくの欲しいもの ちょうだい
via http://b.hatena.ne.jp/torin/20110614#bookmark-46762850
// ==UserScript== // ==/UserScript== (function(){ if (null != window.frameElement) return false; if (! location.pathname.match(/^\/li\//)) return false; window.addEventListener('DOMContentLoaded', function() { var curator = document.querySelector('div.balloon_box.info_prof div.balloon_img.tltip').getAttribute('title').toLowerCase(); var tweeters = document.querySelectorAll('div.tweet_box div.status div.status_right a.status_name'); var len = tweeters.length; var tweeter = ''; for (var i = 0; i < len; i++) { if(curator != tweeters.item(i).textContent.toLowerCase()) { break; } } if (i >= len) { var data = 'data:image/png;base64,'+ 'iVBORw0KGgoAAAANSUhEUgAAAKQAAAA9CAYAAAAj3MLKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC'+ 'vUlEQVR4nO2YS27DMAxEffNerOteq0UDFEgXkinxMyN6FrOKYT0On5Ki18fX56UoLIEDKMp7Yl92'+ 'Xd9/SYWenFPFoCTtNuxFbyJkCjE7p4pByUuJKKHAErJ1UkXJEEJC9k66LNFSSMjeiX9hspTMQuoi'+ 'BHSYvZjoJbEKib4MXVK6oIglScjeKV+Sd1ESsncgi/IsS0L2DmxZuwuTkL1Td1CQlBKyd2oPC5BS'+ 'QvZO/YFOKauFHPF6g148azCHOpZUKWSWjBKTTEiPlN2ElJQkQu5KKSF7Bw/glHLlM0nJn9LS0am+'+ 'WFEX8El5jIzZi185y/Iseh4JKSHdu0DLJCGJFmY97+QZS4SsKIkhBTebQsjTxYQDrCwNzeUVstsl'+ 'fIyQJ0oZJWRUT+x9DedBA+yUjeayslbJ00lKOMBu2WguC2e1NKd0NZ0BDdClaI+QT+tqyo8G6FL0'+ 'jK3655S5p1t2NIC3aJayd4R8Yk+37GiALmWPmFC8jB2ZuNEAUWWjC5/9LCM4I8/OmGF4gdFyMRSe'+ 'yYNkjDg7Y45pP2ixMiRgYkGySUgiEVg42Jgi50rpCi1UpgwMDGzf2pFzpXS1W/ApYRASIWMrIdES'+ 'dRISJWOUkJHvsbyzrYgS8sz/RbYW8skyHi8kWp5uMjIsn5HJLSQakD0SMph5Vioajj0s39JWNnRf'+ 'Ju6T4dkWztQhG4+Z+2R4pmUzdcjGs8Q+GgANxhwJmcg+GgANxhqrjKgOmVi2+EdDoMEYsyIjokMW'+ 'DtcMo0HQYGy5Ew/dIdPFcM3BUOYJYRayi4yvWWYDoeFYYlk4qr9OMr7muRsMDQgtZ+FvRDYh0d1t'+ 'z2Mtv0syZEQJ2U3Gf0JKSruQ1ucRMkrIA+NZ+MrzktEp5FPE3F165POScUHIzlLuLj/j+Ugh0SKl'+ 'C6lwprOMr/nQAMrG0prK+JsfF3m2CCi6mVcAAAAASUVORK5CYII='; var div = document.createElement('div'); var img = document.createElement('img'); img.setAttribute('class', 'za-wa'); img.src = data; function remimg() { var rem = document.querySelector('img.za-wa'); if(rem) { window.setInterval(function() { rem.style.opacity -= 0.05; if (rem.style.opacity == 0) { document.body.removeChild(rem); return; } }, 100); } } function addimg() { var c_img = img.cloneNode(false); c_img.style.position = 'fixed'; c_img.style.top = Math.floor(Math.random() * 100) + '%'; var leftp = Math.floor(Math.random() * 100); if(leftp < 50) { leftp = Math.floor(leftp / 4); } else { leftp = 100 - Math.floor(leftp / 4); } leftp += '%'; var ratio = (120 - Math.floor(Math.random() * 70)); c_img.style.left = leftp; c_img.style.zIndex = -1; c_img.style.opacity = 1; c_img.style.width = (Math.floor(164 * ratio / 100)) + 'px'; c_img.style.height = (Math.floor(61 * ratio / 100)) + 'px'; document.body.appendChild(c_img); var r = Math.floor(Math.random() * 1000) + 1000; window.setTimeout(addimg, r); window.setTimeout(remimg, 2500); } addimg(); } }, false); })();
Javaだけど。
class HelloWorld { public static void main(String args[]) { System.out.println("Hellp World"); } }
fooのintへのキャストがtrue/falseを返すというように、fooのクラス仕様が決められてるんなら、
そしてboolへのキャストが未定義だったり、また違う意味なのなら
if (foo) {
ではなく
if (foo == true) {
って書かざるをえないだろう。嫌いとか好きとかの問題ではないと思う。
class { public: operator bool() { std::cout << "xxx\n"; return true; } //*1 operator int() { std::cout << "yyy\n"; return true; } //*2 } foo;
があったときに、「if (!foo)」だったら*1が、「if (foo == false)」だったら*2が実行されるような処理系がある。
最新のVC++だと後者は曖昧だってエラー出るね(たぶんC++だと「trueは1でfalseは0」なんかではなくあくまでもtrueとfalseなんだ)。
なんにせよ演算子や条件式などに関連する暗黙のキャストはわかりづらく、そしてそんなのを利用したコードはきっとバグる。
だから
というのが本当なら、==trueがどうこうなんて些細な問題はおいておいて、fooを暗黙のうちにintにキャストしたりboolにキャストしたりして使っているという危険な部分をまずなんとかすべきだろう。
古いC言語風に書けばこんな感じ。
#define FALSE 0 #define TRUE (!FALSE)確かに、実際に値を表示させてみると、昔のVC6だと「1」という結果が出てくるし、VB6だと「-1」という結果が出てくる。これ、当時混乱の元だったんだよね。
VC6とか関係なくてC言語の仕様でそうなんだが、それをわかってないとすればやばい。
個人的には
if( foo != FALSE ){
も十分きもちわるいので
if (foo) { ... }
if (!foo) { ... }
にしてほしい。
最新はこれでいいんですか?
誰も話題にしてないので俺だけかな
reblogcount しか動いてなかったので自力で直そうと頑張ってみたが、
一応動画の再生と画像の拡大2種の3つに関しては動くようにできた
likeは使ってないのでとくに見てませんすみません
if (img[n].style.display != 'none') { click($X('./a', img[n])[0]); return stdin; } else{ click($X('./preceding-sibling::a[1]', img[n])[0]); return stdin; }
および
if (mov[n].style.display != 'none') { click($X('.//a', mov[n])[0]); return stdin; }
これは何をしてるんでしょうか?
残したままだとどうもうまくいかなかったので丸ごと削ってしまった
クリックすべき要素を直接XPath指定、にしたんだけどマズイ?
以下patchです
@include に www.tumblr.com/queue* も勝手に足してしまいました
どなたかまともにしてくださいm(__)m
--- 20101127_play_on_tumblr.user.js +++ 20110402_play_on_tumblr.user.js @@ -6,6 +6,7 @@ // @include http://www.tumblr.com/show/* // @include http://www.tumblr.com/tumblelog/* // @include http://www.tumblr.com/tagged/* +// @include http://www.tumblr.com/queue* // ==/UserScript== (function() { @@ -43,25 +44,15 @@ command: function(stdin) { try { if (!stdin.length) stdin = execute('current-node'); - var img = $X('.//div[starts-with(@id, "highres_photo")]', stdin[0]); + var img = $X('.//img[contains(@id, "thumbnail_photo_")]', stdin[0]); for (var n = 0; n < img.length; n++) { - if (img[n].style.display != 'none') { - click($X('./a', img[n])[0]); - return stdin; + click(img[n]); } - else{ - click($X('./preceding-sibling::a[1]', img[n])[0]); - return stdin; - } - } - var mov = $X('.//div[contains(@id,"watch_") and .//a]', stdin[0]); + var mov = $X('.//img[contains(@id,"video_thumbnail_")]', stdin[0]); for (var n = 0; n < mov.length; n++) { - if (mov[n].style.display != 'none') { - click($X('.//a', mov[n])[0]); - return stdin; + click(mov[n]); } - } - var timg = $X('.//img[contains(@src,"tumblr.com/tumblr_")]|.//img[@class="inline_external_image"]', stdin[0]); + var timg = $X('.//img[contains(@class, "inline_external_image")]', stdin[0]); for (var n = 0; n < timg.length; n++) { click(timg[n]); }
というわけでサンプルコード書きなおしてみた。
public class Main { public static void main(String[] args) { int count= args.length==0?100000:Integer.parseInt(args[0]); long start=System.currentTimeMillis(); Main m=new Main(); double result=0; for(int i=0;i<count;i++){ result+=m.test((double)(0.1f*i)); } System.out.println(result); System.out.println(String.format("COMPLETE! %d msec",System.currentTimeMillis()-start)); } private double product=0; public double test(double rad){ return this.product+=Math.tan(rad); } }
<?php class Test{ private $product; public function test($rad) { return $this->product+=tan($rad); } } $count =is_null($argv[1])?100000:(int)$argv[1]; $start=microtime(true); $t=new Test(); $result=0; for($i=0;$i<$count;$i++){ $result+=$t->test(0.1*$i); } echo "{$result}\n"; printf("COMPLETE! %f msec", (microtime(true)-$start)*1000);
$java -jar test.jar 100000 -7.524990063072938E9 COMPLETE! 31 msec
$ php -f test.php 100000 -11900078829.3 COMPLETE! 209.314108 msec
うむ。有意な差はあるっぽいな。(結果が違い過ぎてるのはなんか問題があるかもしれん)
多分、変数の型が出鱈目で計算されるようなもんだとPHPは遅くなるのだと思われ。javaは強い型制約があるから、同じ型同士の計算だと速いとか?
サンプルコード。
package test; public class Main { public static void main(String[] args) { int count= args[0]==null?10000:Integer.parseInt(args[0]); long start=System.currentTimeMillis(); Main m=new Main(); for(int i=0;i<count;i++){ System.out.println(m.test()); } System.out.println(String.format("COMPLETE! %d msec",System.currentTimeMillis()-start)); } public String test(){ return "ぽぽぽぽーん"; } }
<?php class Test{ public function test(){ return "ぽぽぽぽーん"; } } $count =is_null($argv[1])?10000:(int)$argv[1]; $start=microtime(true); $t=new Test(); for($i=0;$i<$count;$i++){ echo $t->test()."\n"; } printf("COMPLETE! %f msec", (microtime(true)-$start)*1000);
ぽぽぽ...
COMPLETE! 1008 msec
ぽぽぽ...
COMPLETE! 988.869190 msec
どういうことなのか説明してもらおうか?
http://1-byte.jp/2011/03/20/20_tips_you_need_to_learn_to_become_a_better_php_programmer/
良いPHPerだって?そんなものは丸めてゴミ箱にでも捨ててしまった方が資源の再利用になる分いくらかマシだ。
つまり俺たちがしなくちゃならないことは「より良いPHPerにならないため」に何ができるかってことなのさ。
それじゃ、始めよう。
?>なんて使っちゃいけない。そう俺たちはBAD PHPer。
無駄なホワイトスペースの出力に悩まされるくらいなら対称性なんて丸めてゴミ箱にでも捨てた方がまだマシだ。非対称性こそが賛美。
require_once("config.php");
未だにこんなことやってるやつがいるのかいベイベー。絶対にダメだ。この一行を見たら俺は悶絶する。
ダメだ、早く何とかしないと。
大抵このconfig.phpの中身はこうなっている。見て絶望だ。
$hoge_path = ''; if (!LOCAL) { define('FOO_FLAG', 1); if (HONBAN) { define('HOGE_FLAG', 1); } else if (TEST) { define('HOGE_FLAG', 2); } } else { $hoge_path = '/local'; define('FOO_FLAG', 2); define('HOGE_FLAG', 3); } define('HOGE_URL', $hoge_path.'/hoge/');
こういうのが延々と続くわけだ。もういやだ。もう見たくない。
本番環境とテスト環境でどういう値の違いがあるのか、ローカル環境だとどうなるのか、まったく把握できる気がしない。
なまじPHPな設定ファイルのせいで、処理をついつい書いてしまう。そしてどんどん複雑になってしまう。
やはり設定データは基本的にYAML等のデータしか定義できない形式のもので用意すべきだ。そして環境ごとに設定ファイルを分けるべきである。
そうすることで何にどういう違いがあるのかすぐにわかるし、diffすれば一度にすべて把握することができる。
# 本番環境設定ファイル foo_flag: 1 hoge_flag: 1 hoge_url: '/hoge/'
# テスト環境設定ファイル foo_flag: 1 hoge_flag: 2 hoge_url: '/hoge/'
# ローカル環境設定ファイル foo_flag: 2 hoge_flag: 3 hoge_url: '/local/hoge/'
// ここで後の処理のためにhogeメソッドを呼び出しておく $q->foo(); // $a['foo']はここに来る時点で真のはず // 2010-03-10 判定がおかしいので修正 // 2010-06-21 やっぱり値が入ってる方が正しい if ( !isset($hoge[0]) ) { }
コメントは保守されない。そう、それは真実。こんなコメントを発見したら即効削除しよう。コメントは基本信じるな。
俺たちにちょっとしたヒントと大きな損害を与えてくれる、それがコメントの役割なのだ。
わかる。いいたい事はとてもわかる。俺たちはしばしばインデントにスペースを使うはずだ。一方でIDEのしっかりした言語ではタブも使うことがある。しかし悪いことに、両者を混同しているプログラマも一定数いるのだ。
タブを画面上で認識しにくいエディタが世の中には存在する(何とは言わないが)
そして画面上で認識しにくいことを理由にタブを気にしないプログラマがいる。
この二つの条件が重なると、タブとスペースの交じり合ったインデントが完成する。もうぐちゃぐちゃだ。これは永遠に続く戦いだ。
私たちが勝利を掴むためにできることなどせいぜい、常にスペースしか使わない。タブを見つけたらその都度スペースに変換する。そういった地道な活動が明日へとつながるのだ。
われわれがプログラムをするとき、何に一番時間がかかってるか。実は変数の命名なのである。ここで拘り過ぎて時間をかけ過ぎては何も進まない。
御託はイイからさっさと書け、だ。しかしとはいっても変数名は重要。日頃からどういうときにどんな名前を使うかを決めておくといい。
そして変数名に型はまったく必要ない。型宣言のないPHPにおいて、型の変数名をつけること自体ナンセンスだ。
$iNumber = 'aaa';
になんの意味もない。コメントを信じるなでも言ったが、これはプログラマを混乱させるだけの害悪なものだ。
変数を使う前に初期化するのは、警告を出さないという意味でも良い癖だ。しかし具体的にどこでやるかが問題だ。
$foo = null; $foo = $q->foo();
こんな初期化に意味はない。よくあるのはやはり、if文で値を振り分けるケースだろう
$foo = null; if ( $hoge ) { $foo = 1; } else if ( $bar ) { $foo = 2; }
このときの初期化はとても有効だ。もしnullの初期化を忘れたまま$fooを使うと警告が出るが、ちゃんと初期化してるので出ない。基本中の基本だ。
function getStatus() { $bReturn = false; if ($i == 2) $bReturn = true; return $bReturn; }(中略)
もし、何かしらの理由で、あなたの書いたif文が間違っていたら?
この書き方をしていれば、間違った値に対して、常にfalseが返る。
私たちが、PHPでsensitiveなデータを取り扱うなら、正しいデータが入力されるまでは、動かないコードを書くべきだ。
trueとfalseの条件がいまいち明確ではないが、本当に動かないコードを書けというのであれば以下のようにすべきだ
function getStatus() { $bReturn = false; if ($i == 2) $bReturn = true; else if ($i == 1) $bReturn = false; else throw new Exception("bad status! $i"); return $bReturn; }
中途半端にfalseを返して生存させる必要性はまったくない。今すぐ死ね!
連想配列のキーを指定する場合だけ定数と間違わないようにクオートで囲まなければならない。そして逆に定数を使いたい場合はクオートで囲ってはいけない。
更に後世のプログラマが処理を見たときに、定数が使いたかったのか、文字列が使いたかったのかを明確にしたい場合はconstantを使うと良い。
// 定数のFOOを使うよということが明確になる print $a[constant('FOO')];
もし、文字列を変数の値と一緒に出力するとき、PHPではコンマの代わりにprintfを使うことが使える。
printf( “Hello, my name is %s“, $sName);
以下の代わりに上記のコードを使う。
echo “Hello, my name is “, $sName;
出力すべき変数が増えれば増えるほど、有効になっていく。とにかく迷ったならば、printfを使え、だ。
三項演算子はとても有効だ。しかし優先順位に難があるせいで、三項演算子をネストしようとすると以下のようなコードになってしまう
$n = (($i == 1) ? 2 : (($i == 2) ? 3 :$i));
括弧だらけで読みにくいったらありゃしない。三項演算子を使うなら一回まで。約束守れないやつは丸めてゴミ箱にでも捨てちまえ。
if ( $flag ) { }
仕様をちゃんと把握しているなら真偽値のチェックなどこれで十分。
もし事前にbool型だというのが確定してるのなら「$flag === true」を使えばいい。
インクリメント、デクリメント演算子は前に付くか後ろに付くかで意味が変わるので慣れるまでは非常にややこしい。
わけがわからなくなるくらいなら初めから使わないほうが良い。見極められないなら使うな。それがPHPerなのだ。
文句なしだ。これは文句がない。
他にも色々あるので覚えておこう
$a %= 1; $a &= 1; $a |= 1; $a ^= 1; $a <<= 1; $a >>= 1;
てっとり早く画面に表示する際にpreはよく使うが、デザインの関係上画面の文字が見えないときがある。
なのでdivを使って以下のようにしとくと便利だろう。
function p($var) {
echo "<div align='left' style='background-color:white;color:black;'><pre>";
print_r($var);
echo "</pre></div>";
}
君らが通常作るアプリケーションなんぞに、定数なんぞ必要ない。いいか、もう一度言う、お前ら程度のもんが、定数使おう何ぞ、おこがましいわ!
大丈夫。なんでもかんでも定数にする必要はない。結局設定ファイルに定数をずらずら作りまくってわけがわからなくなってるパターンが多い。
貴様みたいなもんに、定数は制御できん。いいか設定ファイルはYAML等のデータで持つようにし、その連想配列のデータ構造を一つ持ってるだけで定数の変わりになる。
このメリットに比べれば、定数だと書き換えられなくて良いという利点などこの歯のカスほどのものだ。そんなものは丸めてゴミ箱へ捨ててしまうといい。
認識を改めろ。俺たちはより良いPHPerにならないために努力している。
class Request { private $parameters; private $method; function __construct () { $this->method = $_SERVER['REQUEST_METHOD']; if ( strtoupper($this->method) === 'POST' ) { $this->parameters = $_POST; } else { $this->parameters = $_GET; } } function param ($key) { return isset($this->parameters[$key]) ? $this->parameters[$key] : null; } }
これだけでもいい。たったこれだけでもとても便利だ。ここから拡張してGETやPOSTを明示的に取るメソッドとかも作ってみるといい。自分の手を動かすのだ!
例が良くない。こんなのは引数が20個ある関数から、setを20回呼ぶオブジェクトに変わっただけではないか。
そもそもこの20個の引数とはなんなのか。何かのデータ構造なんであれば連想配列にして引数一つとして渡すべきだし、それぞれまったく異なる用途の変数なのであればWindowsプログラミングじゃあるまいし、20個も引数取る時点で設計が間違えている。
何がいいたいか。別に関数でもオブジェクトでもどっちでもいいということだ。
そんなことで悩んでる暇があったら設計を見直せ。
スキあらば自分自身を返せ。スキあらばオブジェクトを返せ。配列はArrayObjectのARRAY_AS_PROPSで返せ。
ひたすらメソッドチェイン。来る日も来る日もメソッドチェイン。とにかくメソッドチェインを使い続けろ。そこに未来はある。
どんなコードも繰り返すな。もし、少しでも同じコードを書いていたなら、それは関数に置き換えてしまえ。
・・・と、いうのはやめなさい。
一見同じように見えた処理でも前後の流れでまったく違うものということが往々にしてある。
まとめ方にも問題があるケースもある。何でもかんでも関数化すると、関数が膨大に増えていく。君は見たことがあるだろうか。common.phpやfunction.phpの恐ろしさを。
確かに細かく関数化はされているが、適切に関数化していないのである。結合度が非常に高い。なんでもかんでも盲目的にまとめれば良いという話ではないのだ!
あまりに極度に意識しすぎると、プログラムそのものができなくなる。そういう状態に陥る。
気を抜いて。そう気を抜いて。所詮あなたのコードなんてすぐに消えてなくなるよ。きっともっと偉い人が作り直すよ。だからまずは思うが侭にやるといい。
結合度を減らすというのは非常に難しい。何度も何度も失敗し続けて、ようやくここは分けた方が良かったんだなと気付く。次に活かそうと心に決める。そしてまた同じ過ちを繰り返していくわけだ。
まずは実装することだ。これが一番の早道だ。まずはがっつり結合した関数をあえて作るといい。何も考えずに作ろう。
そしてその後に、一部分使いまわしたいとおもうことがあるはずだ。その時に関数に切り出そう。それを繰り返すといい。そのうち初めから分けた方が良いと気付く。
何事も経験が必要である!経験を積まないプログラマは丸めてゴミ箱に捨ててしまえ。
さて、先の例で言うならば、私ならadd_result_outputという関数を作ってしまうだろう。だって、addとresultを連続して呼ぶのはめんどくさいんだもん。一連の流れをいつも使うのなら、その流れをやってくれる関数を作ればいいじゃないか。
function add_result_output ($iVar, $iVar2) { $r = add($iVar, $iVar2); echo result($r); }
もっと言えばクラス化してしまってもいいかもしれない。どんな感じになるかは君の手を動かして確認しよう!
このTipsはとてもわかりにくく、ニッチ過ぎる部分も多いかもしれない。
あくまでも「より良いPHPerにならないための20Tips」なのだ。
君はこの記事を鵜呑みにしてはならない。PHPをPHPと見抜けないPHPerはPHPを使うのは難しい。
もし、あなたがPHPプログラマなら、公式のPHPドキュメントはあなたのケツの穴を拭くための紙になるだろう。
私は、それぞれのセクションを眺めて、各関数でどんなことが出来るかなんぞ、歯クソのゴミ程に役に立たないとおもっている。動けばいい。はは。
あなたは、PHPで用意された既製関数で多くのことが実現できることに、(俺の仕事を減らすなと)驚くはずだ。
この記事があなたの役に立たない事を。
ふざけんな!
この記事に書かれている内容は、丸めてゴミ箱に捨てた方が良いレベルです。
これは http://anond.hatelabo.jp/20110316202255 の続編です。
GTをやる前に改を書いてくれている人がいてとてもしっかりした内容なのでちゃんと勉強したい人はそっちを見てね!
d:id:ryoasai:20110317 - ドラゴンボールで学ぶオブジェクト指向 改 | 達人プログラマーを目指して
またオブジェクト指向については
d:id:m-hiyama:20080109 いまさらながらだけど、オブジェクトとクラスの関係を究めてみようよ | 檜山正幸のキマイラ飼育記
がとても詳しいです。合わせて読むとかなりしっかりと理解出来ると思います。
ホットエントリに行くとは思っておらず、皆様ありがとうございます。
「ドラゴンボールをオブジェクト指向にする」というコンセプトではなく、「オブジェクト指向を(無理矢理)ドラゴンボールで説明する」という遊びだったので
プログラマーの方々にはツッコミを受けてしまいましたがここは遊びだと思って楽しんで下さい…。
ドラゴンボールは小さい頃から大好きでしたが流石にうるおぼえ過ぎました。
それはさておき「説明する題材を決める→好きな漫画から無理矢理当てはまりそうな例を考える」という思考実験なので、気が向いた方は色々考えてみると楽しいと思います。僕は楽しかったです。
これは難易度が高そうです。
やっぱりドラゴンボールで例えると分かりやすいな!
無理がある!
デザインパターンとはドクターゲロが考えた「こうやって設計すれば色々捗るぞ」という例のことです。実際はGoFという人たちが考えたもので23個のよくあるパターンに名前を付けて整理してくれたわけですね。
23個の中にはブルマさんですらわからないものが多いので(さすがドクターゲロですね)良く使う、代表的な物をいくつか紹介します
Singletonは世界に一つだけしか存在出来ないようにする方法です。
balls = new DragonBalls(); //これでは誰でもドラゴンボールを作れてしまう! balls.callShenron();
クラスの中にはいくつかのメソッドがありますが、簡単に言うと外から呼べるもの、外からでは呼べないものの
二種類があります。そうやってメソッドを保護することで世界の崩壊を防ぐわけですね。
基本的な戦闘力をアップさせるには本人の努力が必要になり、外から簡単に挙げられてしまうとジャンプの三本柱が外れてしまいます。
ただナメック星の最長老や界王神などはかなり偉いので、本人の才能を引き出すことが可能でした。
現実には思いつきのような仕様を後から言われることが多々あります。困ります。
//地球上にひとつだけ存在するドラゴンボールをつくろう class DragonBalls{ private DragonBalls(){ //ドラゴンボールを作れないように生成メソッドを保護します。 } static function sagasouze(){ static singleton_dragonball; //ドラゴンボールを生成。 //DragonBallsクラスの中なので、保護してある「new DragonBalls()」を呼べます。 if(!singleton_dragonball)singleton_dragonball = new DragonBalls(); return singleton_dragonball; } }
地球のみんなは地球語しか話せませんが、ナメック星にいるクリリンを通して願いを叶える必要があります。
クリリンももちろん地球語しか話せませんが、ナメック語を話せるデンデがいるため、地球のみんなは願いを叶えることが出来ます。
class Kuririn{ private dende = new Dende(); function request( wish1, wish2, wisth3){ this.dende.request(wish1); this.dende.request(wish2); this.dende.request(wish3); } } kuririn.request( "ピッコロを生き返らせてくれ", "ピッコロをナメック星へとワープさせてくれ", "ナメック星にいる孫悟空とフリーザ以外を全員地球へとワープさせる" );
この場合のメリットはデンデが何をやっているかクリリンをプログラミングした人が知る必要が無いということです。
地球の人はナメック星にいるナメック星人が「デンデ」であることを知る必要もありません。
それでも願いは叶うんです。
本来であればデンデやクリリンは願いが叶うのを待つ必要がありましたが、地球の人は一気に伝えることが可能なように設計しました。
//デンデクラス。ナメック星人は英語でNamekianらしいです。 class Dende extends Namekian{ function translate(word){ namekian = *****//ナメック語に翻訳します。 return namekian; } function request(wish){ static polunga; if(!polunga){ polunga = DragonBalls.spell("タッカラプト ポッポルンガ プリピット パロ"); } polunga.ask(this.trasnlate(wish)); } }
大まかなアルゴリズムだけ決めておいて、実装はサブクラスに任せる設計がTemplate Methodです。
ナメック星に行く方法を考えた時いくつかの方法がありました。古い宇宙船を探してきて直して載せて…っていちいち書くより同じメソッドでナメック星に行けたほうが便利ですね。
abstract class WayToNamek{ abstract function prepareSpaceShip(); abstract function launchSpaceShip( ship ) ; function gotoSU839045YX( people ){ ship = prepareSpaceShip( ); //船を修理します ship.load(people); //人を載せます this.launchSpaceShip(ship); //船を出発します。 } }
ナメック星に行く方法を定義したので「ブルマ、クリリン、悟飯」組と「悟空」をそれぞれナメック星に連れて行きましょう。
way = new WayWithKamisamaShip(); way.gotoSU839045YX( buruma, kuririn, gohan ); way = new WayWithSaiyajinShip(); way.gotoSU839045YX( goku );
と簡単に方位SU83、距離9045YXまで乗員を連れて行くことが出来ます。
二つの方法を実装します。神様の船を修理して行く方法と、サイヤ人の船(悟空が乗ってきた船)で行く方法の二つです。
//神様の船で行きます。 class WayWithKamisamaShip extends WayToNamek{ function prepareSpaceShip(){ return new KamisamaShip(); //船を準備します。神様の船を使います。 } function launchSpaceShip(ship){ ship.inputByVoice("ナメック星に出発"); // } } class WayWithSaiyajinShip extends WayToNamek{ function prepareSpaceShip(){ return new SaiyajinShip(); //船を準備します。サイヤ人の船(フリーザの船?)を使います。 } function launchSpaceShip(ship){ //audio = new HighSpecAudio(); //ship.setAudio(audio); ship.turnOnCenterButton(); //真ん中のボタンを押すだけ } }
元になる船も違いますし、発射の仕方も違いますが同じ呼び出し方が出来ます。
オーディオの位置が決まりませんでしたが、今回の運用では不要とのクライアントからのご意見でしたのでだったので
せっかく用意したオーディオも無駄になりましたが、コメントアウトしてあります。
http://anond.hatelabo.jp/20110316202255 - ドラゴンボールで学ぶオブジェクト指向
また、ポイポイカプセルのように技を塊にして色んな人が使えるように出来ます。
var shotKamehameha = new function(){ //かめはめ波を打ちます。 } noumin.kougeki = sendKamehameha; buruma.kougeki = sendKamehameha; noumin.kougeki(); //カメハメ波がでます。
って書いてるけど、クロージャってのはそういうものじゃないよなぁ、と。 まあファーストクラスの関数オブジェクトっていうところはあってるけど、それだけでクロージャと言えるのかというとちょっと違う。
"a closure is a first-class function with free variables that are bound in the lexical environment." (Closure - Wikipedia) とあるように、関数内の変数がレキシカルスコープに結び付けられているようなものがクロージャなのである。 JavaScript で例を書くなら、次のようになる。
// クロージャを返す関数 var getClosure = function getClosure() { // クロージャからアクセスされる変数 var counter = 0; // クロージャ var closure = function closure() { return counter++; }; return closure; }; // クロージャを取得 var closure = getClosure(); // クロージャを実行 closure(); //=> 0 closure(); //=> 1 closure(); //=> 2
http://anond.hatelabo.jp/20110316202255
亀仙流やつ鶴仙流など、世の中にはいくつかの流派があり、それぞれ カメハメ波やドドン波、舞空術などの技(メソッド)がある。 実際に技を使う場合、技を覚えているZ戦士(インスタンス)が必要。
クラス = 流派
メソッド = 技
インスタンス = Z 戦士
というのはおもしろいと思うし, 例えばゲームを作るなら実際にそういう実装になると思う.
例)セルを作りましょう。 class Cell extends Goku,Veget,Picoro,Tenshinhan,Kuririn{ .... } cell_inst = new Cell(); cell_inst.shotKienzan(); //Kuririnをextendsしているので気円斬が使えます。
しかし, ここではクラス = Z 戦士になってしまっているので, 混乱を招くだろう.
むしろ, 「JavaScript における prototype」 に絞って説明するのはどうだろう.
(ついでに「撃つ」の現在形は shot でなく shoot ですね)
var Goku = function () {};
Goku.prototype.shootKamehameha = function () {
console.log("波!!!");
};
var goku = new Goku;
goku.shootKamehameha(); // 波!!!
var Gohan = function () {};
Gohan.prototype = new Goku;
var gohan = new Gohan;
gohan.shootKamehameha(); // 波!!!
そしてセルによる吸収は, 動的な継承として考えるのがより自然だろう.
var Goku = function () {};
Goku.prototype.shootKamehameha = function () {
console.log("波!!!");
};
var Vegeta = function () {};
Vegeta.prototype.shootBigBangAttack = function () {
console.log("ビッグバンアタック!!!");
};
var Cell = function () {};
// 吸収メソッド
Cell.prototype.absorb = function (target) {
for (var method in target) {
this[method] = target[method];
}
};
var goku = new Goku;
var vegeta = new Vegeta;
var cell = new Cell;
cell.absorb(goku); // 悟空を吸収
cell.absorb(vegeta); // ベジータを吸収
cell.shootKamehameha(); // 波!!!
cell.shootBigBangAttack(); // ビッッグバンアタック!!!
そして次にクロージャの使用例として挙げられた次の例.
例)連続エネルギー波 var shotRenzokuEnergy = function( count ){ var shotEnergy = function(){ //エネルギー波を放ちます }; for(var i=0;i<count;i++){ shotEnergy(); } };
この実装では, shotRenzokuEnergy を実行するたびに shotEnergy が毎回定義されてしまい, 非効率である.
以下のように書き換えることで, shootEnergy の定義は, shootRenzokuEnergy の定義時の 1 回のみとなる.
var shootRenzokuEnergy = (function () {
var shootEnergy = function () {
console.log("エネルギー波!!!");
};
return function (count) {
for (var i = 0; i < count; i++) {
shootEnergy();
}
};
})();
shootRenzokuEnergy(10); // エネルギー波!!! x 10
亀仙流やつ鶴仙流など、世の中にはいくつかの流派(=クラス)があり、それぞれの流派にかめはめ波やどどん波、舞空術などの技(メソッド)がいくつかあります。
実際に流派にある技を使う場合、技を覚えているZ戦士(インスタンス)が必要になります。
例)亀仙流を覚えた孫悟空を使ってかめはめ波を放って敵を倒す goku = new KamesenRyu("goku"); goku.shootKamehameha(teki);
Z戦士によっては複数の流派の技が使えたり、自分の技を人に教えることが出来ます(継承)。
また悟空とクリリンのように同じ流派でも同じ技で違う性能を持っていたり、オリジナルの技を持っているなどの違いがあります。
クラスはセルを作るためのZ戦士達の遺伝子情報と言っても良いかもしれません。
例)セルを作りましょう。 class Cell extends Goku,Veget,Picoro,Tenshinhan,Kuririn{ .... } cell_inst = new Cell(); cell_inst.shootKienzan(); //Kuririnをextendsしているので気円斬が使えます。
世界(プログラミング言語)によってはただの人を後付でZ戦士にすることが可能です。
(JavaScriptやRubyなど)
noumin = new Hito();
noumin.kougekiKuwa = function(){
//戦闘力たったの5…ゴミめ!
};
noumin.shootKamehameha = function(){
//な、なんだと!?
};
農民がいきなりかめはめ波をうつようになったら危険ですね、危ないです。
このように後付でメソッドを追加出来るタイプは危険性を含んでいます。
とても良いつっこみが来たので追記します。
前半部分ではZ戦士をインスタンスとしましたが、セルを作るにはZ戦士がインスタンスでは出来ないので
何をインスタンスにして、何をクラスにするかが「設計」なんですね。
セルの第一段階ではGokuなどのZ戦士の遺伝子があれば作ることが出来ました。
cell_inst = new Cell(); //このセルは第一段階
cell_inst.absorb(17gou); //第二段階に変身 cell_inst.call18gou(); cell_inst.absorb(18gou); //最終段階に変身 class Cell ....{ function call18gou(){ if(!this.17gou)return error(); //17号を吸収していないと失敗する this.17gou.speak("****略*****ドクターゲロ様****略****"); } }
17gouを吸収したので、17号の声で18号を呼ぶことが出来るようになりました。
でもドクターゲロ「様」って言ったのでセルだってバレバレですね。
http://anond.hatelabo.jp/20110316224648
クロージャについてちゃんと書こうと思って挫折。どなたか良いアイディアを下さい。
変数のスコープを解説する必要があるかなと思ったんですがオブジェクト指向からは外れるような気がします。
エネルギー波→連続エネルギー波がどこかに使えそうな気がしましたが、気のせいだったぜ…
みたいな感じで、関数コールを嫌う文化だからなぁ突き詰めると。
そういう事をしようと思わない。別な書き方をするとかじゃなかろうか?
いちおう、C++ならクラス内にクラスは書けるから似たような事はできる。
C/C++は文化的に速度とメモリを重要視する言語だから、あんまりね、そう言うのは主流じゃないと思う。
class A{
private:
int A:
public:
A=a;
}
}
みたいなことも・・・あまり、おすすめできないし・・・。論理的には美しいんだけど・・・いろいろ弊害もあると考えるのがC/C++
ましていわんや、関数内。
※一番痛いのは、設定関数が1箇所なので、動作変更がすぐできる>>大規模システムではコードカバレッジがあるので、
根元の関数の挙動を大きく変えられたら、上位のクラスの莫大なテストやり直しだから、1箇所変更で全箇所変わるのはデメリットw。上位で修正が基本。
というか、やっちゃだめwww。
たとえば、intをdoubleにとかなら、それもう別物だから、上位も変更でしょ。普通・・・。とか。
あと#define関数はデバッガーでおえないので、なるべくC++のコンパイラ通してinlineで書いてぇぇぇぇとか。色々。むしろ#defineで複雑なことしないでー
最近は、24インチ 30インチディスプレイなんて安いんだから、横80ではなく横120ぐらいは平気で使える。
classname::enumname という毎回指定でも エディタがインテリジェントに保管してくれるから問題ない。
基本的に 外部ツールがチェックしてくれるんだから
enum{
{
};
で問題ないと思われ
言い方を変えれば、class内部以外でenumを定義することなんて最近はあるのか?グローバルなenumなんて余り無いと思うが・・・
クラス内部では、省略できるし、外部から、クラス内部の値を呼ぶときは、どのクラスのこのenumって外部だよって意味で毎回書いたほうが安全だろ?
using namespace std
ですら、書かないほうが安全 毎回std::って書かないと、うっかり、stringクラスを定義する人がいないとは限らんからね・・・
一斉に変更したい? エディタに正規表現で置換すればよろしい・・・
原則、外部のツールで解決できる問題は、外部のツールで解決すればいい。
言語仕様を拡張されると、初心者に、その理屈を説明するという問題が出てきて、そういうのは初心者には無理。
他方、ツールを使えない初心者でも、毎回コピペや手で置換は出来る。
pタグやdivタグのclass要素を指定できるのでHTMLでそのまま記述する。
いつくかはてなダイアリーでの使用可能なはてな記法は無効になっており、例えばキーワードリンク無効記法が使えないためフォントカラーが キーワードリンクの黒に潰されちゃうかんじ。
以下サンプル。アルファベットはクラス名(自動アンカーついていててコピペしにくい。ソースみたほうがいいかも)。
a.keywordcloud10 を空白で刻むことによってうざいかんじになる。荒し用。
オブジェクトのシリアライズツールであるプロトコルバッファについて書きます。
Protocol Buffers 本家
http://code.google.com/apis/protocolbuffers/
XMLはもう不要!? Google製シリアライズツール「Protocol Buffer」
http://journal.mycom.co.jp/articles/2008/07/18/protocolbuffer/index.html
Protocol Buffers (Protocol Buffers の内部解説記事。とても参考になります)
http://dodgson.org/omo/t/?date=20080712
プロトコルバッファは異種言語間でオブジェクトのやりとりをするための規格です。
独自の言語によりオブジェクトのインターフェースを規定することで、多言語対応を行っています。
例えばこんな感じ。
package tutorial; message Person { required string name = 1; required int32 id = 2; // Unique ID number for this person. optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } // Our address book file is just one of these. message AddressBook { repeated Person person = 1; }
以上のようなprotoファイルから各言語のソースコード、または何らかのデータ操作ライブラリを使いオブジェクトの処理を行います。
googleによってC++, Java, Python用のライブラリが作成されましたが、他の言語に対応したサードパーティー製のライブラリがいくらでもあるので、実質的にほぼすべての言語で使えると言っても過言ではありません。
数字が多きければ大きいほど、長いバイト長で保存されます。ただし、負数の場合は符号ビットが立つ関係で、ほとんど常に変換後のバイト数が最長バイト数(10)になってしまいます。フィールドの型をsint32, sint64で宣言しると、各数値にzig-zags変換が行われるため、負数であってもその値の絶対値で使用バイト数が決まるようになります。
バイナリに保存されるデータは各メッセージのID/型/値のみです。なので、同じ定義の二つのメッセージ型は、プロトコルバッファ上では全く同じように扱うことが出来ます。例えば、片方からシリアライズしたデータを、もう片方の型でデシリアライズすることが可能です。
またオブジェクトを連続でシリアライズ/デシリアライズすることもできます。
すでに存在する継承関係のあるクラスを、Protocol Buffersでシリアライズ/デシリアライズしたい場合は次のようにします。
(ソースコード中になぜか日本語が書けないので、コメントはすべて英語になっています)
message PbBase { require int32 id = 1; require int32 value = 2; require Derived derived = 10; // - Point !!! } message PbDerived { require string string_value = 1; }
継承元のメッセージの定義に、継承先のメッセージを持たせます。Baseを継承するクラスをシリアライズ/デシリアライズしたい場合は、PbBaseメッセージを中心に処理を行うことで、比較的簡単に処理を実装することが出来ます。
例えばこんな感じ
Base *Base_DeserializeFrom(PbBase &amp;pbobj) { // Arrange the classes which inherits from Base. if (pbobj.has_derived()) { return new Derived(pbobj); } else ... } class Base { ... virtual void Base::SerializeTo(PbBase &amp;pbobj) { // Set the fields of 'pbobj', } ... }; class Derived { ... virtual void Base::SerializeTo(PbBase &amp;pbobj) { PbDerived *derived = pbobj.mutable_derived(); Base::SerializeTo(pbobj); // Set the fields of 'derived', ... } ... };
protoファイルを以下のように書くと、メッセージの扱いが非常に難しくなります。
message PbBase { require int32 id = 1; require int32 value = 2; } message PbDerived { required PbBase base = 1; // - Here is the point !!! require string string_value = 2; }
ほんとかなあ。いまいち信じられないな。
ちょっとググっただけでこんなもんだぜ。
America, The New Class-Society
http://www.forbes.com/2007/10/09/america-class-society-ent-dream1007-cx_pm_1009class.html
America Becomes a Two-Class Society
http://www.canadafreepress.com/index.php/article/22056
めんどくさくて読んでないけどwikipediaにも色々書いてある。
Social class in the United States
http://en.wikipedia.org/wiki/Social_class_in_the_United_States
出だしからしてA classless society?だからなあ。
JRuby上で動くRubyとJavaのログを同じファイルに保存したいときなど
JRuby界隈で何かいい方法ないかな~と探していたけど見つからないので
RubyのLoggerのインターフェースをcommons-loggingを使用して実装してみた
使用バージョンは以下
require 'logger' class CommonsLoggingLogger def initialize(name="ruby") @progname = nil @logger = org.apache.commons.logging.LogFactory.getLog(name) end def add(severity, message=nil, progname=@progname, &amp;block) if message.nil? and block_given? message = yield end case severity when Logger::DEBUG debug(progname){message} when Logger::INFO info(progname){message} when Logger::WARN warn(progname){message} when Logger::ERROR error(progname){message} else fatal(progname){message} end end def debug(arg0=nil, &amp;block) @logger.debug make_log(arg0, &amp;block) end def info(arg0=nil, &amp;block) @logger.info make_log(arg0, &amp;block) end def warn(arg0=nil, &amp;block) @logger.warn make_log(arg0, &amp;block) end def error(arg0=nil, &amp;block) @logger.error make_log(arg0, &amp;block) end def fatal(arg0=nil, &amp;block) @logger.fatal make_log(arg0, &amp;block) end def debug? @logger.isDebugEnabled end def info? @logger.isInfoEnabled end def warn? @logger.isWarnEnabled end def error? @logger.isErrorEnabled end def fatal? @logger.isFatalEnabled end def level if debug? Logger::DEBUG elsif info? Logger::INFO elsif warn? Logger::WARN elsif error? Logger::ERROR else Logger::FATAL end end def level=(lv) #do nothing end def sev_threshold level end def sev_threshold=(lv) #do nothing end def datetime_format nil end def datetime_format=(fm) #do nothing end attr_accessor :progname private def make_log(message_or_progname, &amp;block) if block_given? progname = message_or_progname || @progname message = yield else progname = @progname message = message_or_progname end progname_message(progname, message) end def progname_message(progname, message) progname.nil? ? message : "#{progname}: #{message}" end end
models.register({
name : 'HatenaAnonymousDiary',
ICON : 'http://anond.hatelabo.jp/images/favicon.ico',
check : function(ps){
return (ps.type == 'link' || ps.type == 'quote' || ps.type == 'regular' || ps.type == 'photo') && !ps.file;
},
getAuthCookie : function(){
return getCookieString('hatelabo.jp', 'rk');
},
post : function(ps){
var endpoint;
if (!this.getAuthCookie())
throw new Error(getMessage('error.notLoggedin'));
return request('http://anond.hatelabo.jp').addCallback(function(res) {
var doc = convertToHTMLDocument(res.responseText);
var user = $x('//td[@class="username"]/a/text()', doc);
endpoint = 'http://anond.hatelabo.jp/'+user+'/edit';
return request(endpoint, {
redirectionLimit : 0,
referrer : 'http://anond.hatelabo.jp'
});
}).addCallback(function(res) {
var doc = convertToHTMLDocument(res.responseText);
var form = formContents($x('//form[@name="edit"]', doc));
var content = update(form, {
title: joinText(['[reblog]',ps.itemUrl], ' '),
body: joinText([ps.item, ps.itemUrl,
(ps.body ? ">>\n" + ps.body + "\n<<\n" : ''), ps.description], "\n")
});
return request(endpoint, {
redirectionLimit : 0,
referrer : res.channel.URI.asciiSpec,
sendContent: content
});
}).addCallback(function(res){
if (!res.channel.URI.path.match(/\/[0-9]+/)){
throw new Error("post failed: " + res.channel.URI.path);
}
});
}
});
このあたりの話題関連。
米 Christian Science Monitor紙から適当に訳出(ちなみにこの新聞、題名とは裏腹に宗教色は薄いことに注意:参考記事)。
ワトソン率いるシー・シェパードの支持者は、第二昭南丸の無謀な行動が衝突の原因だという。批判側は、アディ・ギルの行動が衝突を不可避にしたと指摘する。
第三者としては、この動画からは何とも言えない。
しかし、熟練の航海士や船長たちからメールで寄せられた情報の一致するところでは、全ての船が衝突を回避するためのあらゆる対策を取る責任があり、非難の矛先としては、アディ・ギルのように小さくて操縦しやすい船が、旋回のしやすさゆえ、通常はより多くを負うという。
「長い歴史のある航海航法の原則では、小さくて小回りの利く船の側は意図を明確に、大きくて動きが重い船の操縦を妨げないように求められている」と、元航海士の一人は記す。
同航海士曰く、「小さい船が帆船や人力(手漕ぎ)の船で、大きい船が機械化された船のような例外を除いては、原則は明確に、小さい船にclass上(訳注:航海用語の知識不足のため訳せず)の優先権があったとしても、大きな船をどかせるような状況を回避するあらゆる努力を求めている。理由は単純で、大きな船は小さな船を見て反応するまでに時間がかかり得るからだ。つまり、海軍でも商船でもいうように、『総トン数ルール』が全てに優先するのだ」という。
国際海事機関の衝突関連規定は1972年に制定され、現在も有効であるが、同規定は、アディ・ギルの側に多くの非があるという立場を裏書きすることになりそうだ。アディ・ギルは何日もにわたって、第二昭南丸に乱暴に接近したり、船首に突進したり、レーザーで日本人船員の視力を一時的に奪おうとしたり、金属線でプロペラを止めようとした。以下の動画はクリスマス前に撮影されたもので、そうした行動の一部を物語っている(大音量でテクノ音楽が流れるので注意)。
http://www.youtube.com/watch?v=pR96rKo6M7k
同規定は「全ての船舶は、他の船舶の取り得る限りの進路を避け、早い段階で明確かつ実質的な行動を取ることが求められる」とし、動力船は、「機動力の限られた船」や「漁撈中の船」の進路を妨害してはならないとしている。