https://linen.dev logo
【ゆるぼ】バージョン分けスクリプトの書き方を議論したい
# forum
u
⚠️答えのない問いをここで聞いていいのだろうか?⚠️ ダメだったら消えます おもにスクリプトを日常的に書いたり、プログラミング言語に日常的に触れてる人にお聞きしたい 当方java javascript python vba はなんとなくかけます c++は勉強中 # Q.RTM向けのスクリプト、どうやってバージョン分けを記述してますか? 当方の現状の解 ①三項演算子を使って変数宣言時に代入 ②変数を宣言してから、別々に場合分けして代入 それぞれおはなしします、描き方的には①が好きなんですが、内部処理的には②としたい気持ち 【注意】 ・グローバル変数は使用しないものとし、スクリプト間のデータ共有にはdataMapを使うものとします ・基本的にstring型を使う事は避け、バージョン分けはフラグを立てて、int型などの値で判断する事とします ・可能な限り、単純な記述の提案を希望します 複雑な記述ほどバグを拾いやすいため ①:三項演算子記述 ローカル変数を宣言するとき、例えば
Copy code
function renderExample(entity, version){
    var set1 = ver == 7 && valOld1 1 ? valOld1 : ver == 12 && valLatest1 ? valLatest1 : 0.0 ;
    var set2 = ver == 7 && valOld ? valOld2 : ver == 12 && valLatest 2 ? valLatest2 : 0.0 ;
etc……
}
上のように、都度三項演算子で比較して、バージョンを分ける方式 メリット ・コードがスッキリして、可読性が上がりそう デメリット ・動作を明確に予想できなさそう ②別々場合分け
Copy code
function renderExample(entity, version){
    var set1, set2 ;
    if( ver == 7  ){
    set1 = valOld1 ? ValOld1 : 0.0 ;
    set2 = valOld2 ? ValOld2 : 0.0 ;
    }else if( ver == 12  ){
    set1 = valLatest1 ? valLatest1 : 0.0 ;
    set2 = valLatest2 ? valLatest2 : 0.0 ;
    }

}
バージョン分けをifで行い、宣言と代入を分ける方式 メリット ・バージョンごとに動く動作が確実になる デメリット ・開発がやりづらい、書き落としの可能性が出る 以上二つを考えました より良いやり方をご存知だったり、実際に開発経験のある方がいらっしゃいましたら、ご教示頂けると幸いです よろしくお願いします🙇 【脚注】 ・valOld1 とか ValLatest1 とかには、nullかintの数値が入ります 他の型が入っても後で型絞れば共通で考えて良いかなと思っています ・null避けを確実にするために三項演算子をどちらにも入れていますが、もしかしたらjavascriptって0だとfalseになる時があるので、速度とかの取得には向いてないかもしれません ・より汎用性を上げるために、型ごと、シチュエーションごとにより良い記述があったりしたら、別個教えていただきたいと思います🙏
脚注に追加です valOld1とか、valうんたらかんたらには、nullとintどちらが来るかはわかりません、編成データが壊れるとnullが来たり、気分次第でnullが来ます なおnull値は全く必要ありません、ヌル(ナル)避けのおすすめのやり方も併せて教えて欲しい🙇 0 == falseのうんたらかんたら よう考えたらそこも見越して最後は0が出るようになってたわ。。。 stringに対して使うなら、ここはemptyとかnoneとかblankでもよい Q. 要するに何がしたいの? # A. じょうぶなコードを書きたい == 冗長性に長けたコードを書きたい
h
自分の場合は、最近は極力関数化してそこで差分処理を書くようにしています。 スクリプトの本筋になる部分(renderやonUpdateなど)の中ではあらすじを書き、そこで必要な細々した処理を関数にするみたいな感じです。 例えば
Copy code
js
var isOldVer = RTMCore.VERSION.indexOf("1.7.10") !== -1;

function onUpdate(entity, scriptExecuter) {
    //変数
    var dataMap = entity.getResourceState().getDataMap();
    var world = entity.field_70170_p;
    var rider = null;
    if (isOldVer) {
        rider = entity.field_70153_n;
    }
    else {
        var passengers = entity.func_184188_bt();
        rider = passengers.size() > 0 ? passengers.get(0) : null;
    }
    var ridingEntity = null;
    if (isOldVer) ridingEntity = entity.field_70154_o;
    else ridingEntity = entity.func_184187_bx();

    //処理
    //⋮
}
Copy code
js
var isOldVer = RTMCore.VERSION.indexOf("1.7.10") !== -1;

function onUpdate(entity, scriptExecuter) {
    //変数
    var dataMap = entity.getResourceState().getDataMap();
    var world = entity.field_70170_p;
    var rider = getRider(entity);
    var ridingEntity = getRidingEntity(entity);

    //処理
    //⋮
}

function getRider(entity) {
    if (isOldVer) {
        return entity.field_70153_n;
    }
    else {
        var passengers = entity.func_184188_bt();
        var rider = passengers.size() > 0 ? passengers.get(0) : null;
        return rider;
    }
}

function getRidingEntity(entity) {
    if (isOldVer) return entity.field_70154_o;
    else return entity.func_184187_bx();
}
前者はごちゃごちゃしてるのに比べて後者はスッキリしていて、個人的には保守性(読みやすさ)に優れているかなと思ってます。関数化することで別のスクリプトを書くときに流用することもできます。
あとは三項演算子ですが、入れ子にしたり長文化すると読みにくくなるので、入れ子にしない、条件分岐を変数化して記述量を減らす等をすると(他人にとっても)読みやすくなるかな思います。
Copy code
js
//ワンライナー化できるけど読みにくい
function test(flag1, flag2) {
    return flag1 === flag2 ? flag1 : flag2 < flag1 ? flag2 : flag1;
}

//多少はマシだけど入れ子になってて読みにくい
function test(flag1, flag2) {
    var isSameValue = flag1 === flag2;
    var isMinimumFlag2 = flag2 < flag1;
    return isSameValue ? flag1 : isMinimumFlag2 ? flag2 : flag1;
}

//条件分岐と内容が1:1で理解しやすい
function test(flag1, flag2) {
    if (flag1 === flag2) return flag1;
    else if (flag2 < flag1) return flag2;
    else return flag1;
}

//どういうときに三項演算子が活用できるか?
//記述量が少ないとき/内容が似ているときは活用できる(条件分岐に変数を使うなど)
var branchDir = isLeftDir ? "left" : "right";
var glList = isOldVer ? GLHelper.generateGLList() : GLHelper.generateGLList(null);
var subRailModelSet = isKaizPatch ? subRail.getModelSet() : subRail.getResourceSet();
var startAnchorPitch = (isKaizPatch || !isOldVer) ? startRP.anchorPitch : straightPitch;
//など
あとはちょっと裏技的な話ですが、変数(引数)がfalsyなとき(0、false、null、undefined、NaN、""※空文字 )にOR演算子を使うことで、三項演算子を使わずに初期値を当てる方法もあります。下記の処理はどれも同じ挙動(デフォルト値に0を与える)をします。
Copy code
js
function test(arg1){
    //arg1が0やnull、undefined等であるとき、変数numに0を与える
    var num = arg1 || 0; 

    var num = arg1 ? arg1 : 0;
    
    var num = 0;
    if (arg1) num = arg1;

}
u
OR当てるのかっこいいwwwww
以上参考になります ありがとうございます🙇 他にも思いついた方いらっしゃいましたらお願いします🙏