品質向上WG LT: テーマ:「私が感動した/目から鱗だったコードとレビュー」
2018.9.18 Yasuharu SEKI
まともなプログラマなら
みんな書く
var self = this;
self._promptPluginName()
.then(
function () {
return self._promptDomainName();
})
.then(
function () {
return self._promptPluginID();
})
.then(
function () {
return self._promptPluginVersion();
})
.then(
function () {
return self._promptPluginPlatforms();
})
.then(
function () {
// remaining adjustments
self.props.testbedName = self.props.pluginName + '_TestBed';
self.props.testbedID = self.props.pluginID + '-testbed';
self.props.TEST_FRAMEWORK = TEST_FRAMEWORK;
done();
});
JavaScript 標準的なインデント
var self = this;
self._promptPluginName()
.then( function(){ return self._promptDomainName(); } )
.then( function(){ return self._promptPluginID(); } )
.then( function(){ return self._promptPluginVersion(); } )
.then( function(){ return self._promptPluginPlatforms(); } )
.then( function(){
// remaining adjustments
self.props.testbedName = self.props.pluginName + '_TestBed';
self.props.testbedID = self.props.pluginID + '-testbed';
self.props.TEST_FRAMEWORK = TEST_FRAMEWORK;
done();
});
個人的こだわり
連続した同様のコードは1行に抑えて縦位置を揃える
import * as React from 'react';
// ============================================================================
// CONFIG
//
/* snip */
// ============================================================================
// Type definition
//
interface IProps {}
interface IStates {}
// ============================================================================
// Class implementation
//
export class SampleClass extends React.Component<IProps, IStates> {
constructor(props) { super(props); }
// --------------------------------------------------------------------------
// render
//
render() {
return (
<div>
{this.renderObject1()}
{this.renderObject2()}
</div>
);
}
renderObject1() {
return <div onClick={() => {this.handleSample1()}}>Object1</div>
}
renderObject2() {
return <div onClick={() => {this.handleSample2()}}>Object2</div>
}
// --------------------------------------------------------------------------
// UI action handling
//
handleSample1() {
console.log('click object1');
}
handleSample2() {
console.log('click object2');
}
}
export default SampleClass;
// --------------------------------------------------------------------------
// オブジェクト位置
//
setLeft ( left : number ) { this.left = left; }
setTop ( top : number ) { this.top = top; }
setWidth ( width : number ) { this.width = width; }
setHeight ( height : number ) { this.height = height; }
// --------------------------------------------------------------------------
// オブジェクトのスタイル
//
setContent ( content : JSX.Element ) { this.content = content; }
setColor ( color : string ) { this.color = color; }
// --------------------------------------------------------------------------
// 移動やアニメーション
//
moveTo ( left: number, top: number, duration_ms: number) {
// ... 移動のコード
}
changeColor ( newColor: string, duration_ms: number ) {
// ... 徐々に色を変えるコード
}
プログラマーが「意味が変わる」と思ったところを伝える
// ============================================================================
// クラスの定義開始とか
// ============================================================================
// ============================================================================
// 関数群のセクション開始とか
// ----------------------------------------------------------------------------
// ============================================================================
// コンフィグなどの表題とか
//
// ----------------------------------------------------------------------------
// 関数の開始部とか
//
// 関数内でのコメントとか
Tips: セパレータの意味の強さで表現を変えてる
Tips: 右の終端は 80 文字目にしてる
と信じてる
黄金比
generator-cordova-plugin-devbed / _plugin_platform /index.js
'use strict';
var assert = require('assert');
var yeoman = require('yeoman-generator');
var cordova_lib = require('cordova-lib');
var plugman = cordova_lib.plugman;
//============================================================================
// Yeoman generator implementation
//
module.exports = yeoman.generators.Base.extend({
constructor: function (args, options, config) {
yeoman.generators.Base.apply(this, arguments);
this.props = options;
},
//==========================================================================
// Add platform into plugin
//--------------------------------------------------------------------------
/// CWD changed to plugin directory
///
plugin_changedir: function() {
assert(this.props.pluginName, 'pluginName is required');
process.chdir(this.props.pluginName);
},
//-------------------------------------------------------------------------
// Run plugman: add platform
//
plugin_add_platforms: function() {
this.log('*** Adding platform to plugin ***');
var done = this.async();
this._add_platforms(0, this.props.pluginPlatforms, done);
},
_add_platforms: function(idx, platforms, done) {
if(platforms.length <= idx) {
done();
return;
}
var self = this;
plugman.platform({ operation: 'add', platform_name: platforms[idx] }, function() {
self._add_platforms(idx+1, platforms, done);
});
},
plugin_back_to_root: function() {
process.chdir('..');
},
// finalize this generator
finalize: function() {
if( this.props.done ){ this.props.done(); }
},
});
main(l
,a,n,d)char**a;{
for(d=atoi(a[1])/10*80-
atoi(a[2])/5-596;n="@NKA\
CLCCGZAAQBEAADAFaISADJABBA^\
SNLGAQABDAXIMBAACTBATAHDBAN\
ZcEMMCCCCAAhEIJFAEAAABAfHJE\
TBdFLDAANEfDNBPHdBcBBBEA_AL\
H E L L O, W O R L D! "
[l++-3];)for(;n-->64;)
putchar(!d+++33^
l&1);}
終わりの言葉