Tek satırda birden fazla nesne bildiriminin Jenkins yorumu


9

Bu bir soru değil, uyarıcı bir masal: Yerden tasarruf etmeye çalıştım ve Jenkins Deklaratif boru hattında değişkenlerimi şöyle beyan ettim:

int a, b, c

Sonra onları şu şekilde başlattım:

a = b = c = 0

Kodumda, bu tamsayılar for-loop'ta sayaçlar olarak kullanıyorum. Benim senaryom defalarca başarısız devam etti, bazı istisnalar atıldı:

java.lang.NullPointerException: Cannot invoke method next() on null object

ve zor kodlanmış olduğu için listemin geçerli olduğundan emin oldum. Böylece, bu sayaçlarda neler olup bittiğini merak etmeye başladım ve üzerlerinde getClass () dediğimde Jenkins bana tamsayı olmadıklarını söyledi, aksine

org.codehaus.groovy.runtime.NullObject

Kodu olarak değiştirdikten sonra

int a = 0
int b = 0
int c = 0

her şey bir cazibe gibi çalıştı. Sadece bunu paylaşmak istedim. Belki birinin hayal kırıklığına uğramasına yardımcı olur.

Yanıtlar:


12

Jenkins boru hatları groovy-cps yorumlayıcısı kullanarak devam kodunda Groovy kodunu çalıştırır . Bu doğrudan IDE veya Groovy Shell'de çalıştırabileceğiniz vanilya Groovy değil.

Groovy CPS, kodunuzu, devam eden stili ve doğru Groovy ifadesini desteklemek için dönüştürür:

a = b = c = 0

daha çok benzeyen bir şeye dönüşür:

eval(
  var("a"), 
  assign(
    eval(
      var("b"), 
      assign(
        eval(
          var("c"), 
          assign(0)
        )
      )
    )
  )
)

CPS yorumlayıcısında bu ifadeyle ilgili sorun, atamanın herhangi bir değer döndürmemesi ve bu nedenle nulldeğerin değişkene atanması bve aynı şeyin değişkene gerçekleşmesidir a.

CPS invokasyon bloğunda daha derine inmek istiyorsanız, groovy-cps projesini klonlayabilir ve com.cloudbees.groovy.cps.CpsTransformerTestsınıfta basit bir test senaryosu yazabilirsiniz .

@Test
void testMultiVariablesInlineCPS() {
    def cps = parseCps('''
int a, b, c
a = b = c = 0
''')
    println cps
}

Sonra bir kesme noktası koymak println cpsve hata ayıklayıcı çalıştırabilirsiniz. Denetim penceresini açtığınızda, buna benzer resmi göreceksiniz:

resim açıklamasını buraya girin

Bir yan not olarak, Groovy derleyicisinin kodu bayt koduna derlediğinde tek satır atamalarınızı da dönüştürdüğünü unutmayın. Gibi basit bir Groovy komut dosyası derlerseniz:

int a, b, c
a = b = c = 0

println "$a $b $c"

ve sonra bayt kodunu Java eşdeğerine dönüştürmek için sınıf dosyasını IDE'de açarsınız, şöyle bir şey görürsünüz:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import groovy.lang.Binding;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.GStringImpl;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class test extends Script {
    public test() {
        CallSite[] var1 = $getCallSiteArray();
    }

    public test(Binding context) {
        CallSite[] var2 = $getCallSiteArray();
        super(context);
    }

    public static void main(String... args) {
        CallSite[] var1 = $getCallSiteArray();
        var1[0].call(InvokerHelper.class, test.class, args);
    }

    public Object run() {
        CallSite[] var1 = $getCallSiteArray();
        int a = 0;
        int b = 0;
        int c = 0;
        byte var5 = 0;
        return var1[1].callCurrent(this, new GStringImpl(new Object[]{Integer.valueOf(var5), Integer.valueOf(var5), Integer.valueOf(var5)}, new String[]{"", " ", " ", ""}));
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.