昨日萬聖節ABAP怪獸級代碼謎團,公佈答案啦

首先很是感謝你們在週末還抽出寶貴的時間耗在Jerry昨天發佈的文章 一段讓人瑟瑟發抖的ABAP代碼 上面。git

雖然Jerry在文末開玩笑的聲稱,只有文章閱讀量上千或者評論數超過50,才公佈答案。其實這只是Jerry的玩笑,由於正如Jerry在以前一篇文章 5000粉絲數達成,感謝你們一如既往的支持 裏提到,在微信自媒體氾濫的今天,你們可以在衆多公衆號中關注汪子熙公衆號,並抽出時間來閱讀Jerry或一本正經或胡說八道的文字,Jerry真的很感激,謝謝你們。github

在分析ABAP代碼謎題以前,Jerry還想講一個故事。Jerry 2007年加入SAP成都研究院時,我老闆的老闆是E君,當時就已是在SAP界打拼不少年的老江湖了。E君平時表情嚴肅的時候居多,作事雷厲風行,頗有領導的範,包括Jerry在內的不少剛畢業入職的新人們都很懼怕他(固然Jerry如今不怕了,哈哈)。編程

2008年的時候,Jerry仍是標準的ABAP菜鳥一枚,有一天學到了如何使用ABAP發送郵件給一個Distribution List,並任意指定郵件的SendTo字段。Jerry那時以爲這個技巧很酷(當時的確夠菜的 -_-),正好當時我在開發一個工具,須要向整個團隊的DL彙報進度。因而Jerry在用郵件彙報進度的時候,沒有采用在Outlook裏編寫郵件而後發送的方式,而是寫了一段ABAP代碼,把郵件發送給了整個團隊。不少同事收到郵件後,由於SendTo字段爲空,因此不知道這封郵件是誰發的。當時Jerry以爲這很酷。微信

後來E君把我叫到他的辦公室談工做上的事情時,特地提到了這封郵件,他說他不用猜都知道必定是我發的,而後問我爲何要這樣作,聽完個人解釋以後,先說了句:「之後別這樣。」而後給我分析了緣由。從那之後,Jerry慢慢地開始懂得,做爲一個SAP應用開發人員,再新再酷再吸引眼球的技術,若是不能爲業務服務,不能爲客戶服務,那也make no sense at all.編程語言

回到題目自己。這道題不過是用於萬聖節搞怪消遣的產物罷了,相信沒有任何ABAP開發顧問會在實際工做者去模仿這種風格來編碼。工具

Jerry給你們介紹這個謎題,目的不是在炫耀ABAP這門語言的一些奇技淫巧,而是以爲咱們仍然能夠從謎題自己找到一些積極的因素,好比藉此弄清楚一些平時掌握得似是而非的ABAP語言特性。編碼

(1) 從評論區能看出,不少朋友都找到了謎題的突破口,即 NOT=>NOT( NOT ). 這是典型的ABAP類靜態方法調用的語法,所以說明,在名爲NOT的INCLUDE裏,包含了一個名爲NOT的ABAP類,有一個名爲NOT的靜態方法。同時,這個靜態方法調用的前面出現了OR這個布爾邏輯運算符,只能有一種狀況才能經過語法檢查,就是NOT靜態方法的輸出參數爲RETURNING類型,而後該輸出參數做爲OR的操做數。3d

值得一提的是,不少其餘編程語言都禁止使用關鍵字保留字來命名標識符或者類,而ABAP卻沒有這個限制,顯得有點特立獨行。orm

(2) 也有朋友在評論區提到,代碼可執行部分以IF開頭,可是卻沒有以ENDIF結尾。惟一的解釋,就是在NOT這個include裏,聲明瞭包含ENDIF語句的宏,並把宏的名稱取名爲NOT.blog

(3) ABAP裏感嘆號的用法。

ABAP幫助文檔裏說的很清楚,!做爲ABAP裏的轉義字符,可以告訴ABAP編譯器,!後面緊跟的並非關鍵字,而是普通的ABAP標識符。

給出的例子也很清晰,若是有人非要用CHANGING和USING做爲形式參數的名稱,只須要在前面加上感嘆號便可。

而若是感嘆號後面跟的並非真的ABAP關鍵字,而是普通的標識符,那又會如何呢?

答案是,此時感嘆號會直接被忽略。看下面的例子,加上感嘆號的效果和不加一致。

(4) 如今咱們已經知道了,題目中的!NOT,暗示你們在NOT include裏,還定義了一個名爲NOT的變量。

首先咱們把謎題裏迷惑人眼球的障眼法所有拿掉。

在有NOT參與的ABAP邏輯判斷語句裏,出現偶數個NOT,至關於一個NOT也未出現過(相似負負得正的原理),出現奇數個NOT,只至關於出現一個NOT.

因此題目中那多餘的一系列NOT,就像《笑傲江湖》中衡山掌門莫大先生那套「衡山百變千幻雲霧十三式」中的虛招同樣,能讓不明就裏的對手眼花繚亂。

人稱「琴中藏劍,劍發琴音」的莫大,憑藉這手如夢如幻的劍法,在衡山城外擊殺了嵩山十三太保之一的「大嵩陽手」費彬。即便武功強如費彬,也沒弄看透莫大劍法中的虛招。而親愛的ABAP顧問們,這道謎團中重複的NOT虛招,你們看透了沒?

仔細觀察代碼中全部出現!NOT的地方,按照上述法則去除掉多餘的NOT以後,可以提取出兩個規律:

a. !NOT 前面至少有一個IF,OR或者AND

b. !NOT 後面直接結束,並未出現 IS INITIAL或者 > XXX, <> XXX等判斷語句。

什麼樣的ABAP變量類型容許這種操做呢?

整型不行:

字符串類型不行:

而SELECTION-OPTIONS就能夠。

這個SELECTION-OPTIONS是ABAP古董級的功能了,在SAPGUI下作Dynpro開發的顧問們會常常用,而SAP Cloud Platform ABAP編程環境下已經再也不支持了。

上述四個語法點逐一突破後,如何編寫NOT include的源碼,思路也就清晰了。

源代碼以下:

若是想複製粘貼這段代碼,能夠訪問Jerry的github:

https://github.com/i042416/KnowlegeRepository/blob/master/ABAP/backup/NOT.include.abap

感謝閱讀。

要獲取更多Jerry的原創文章,請關注公衆號"汪子熙":

相關文章
相關標籤/搜索