首先非常感謝大家在周末還抽出寶貴的時間耗在Jerry昨天釋出的文章 一段讓人瑟瑟發抖的ABAP代碼 上面。

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的操作數。
(2) 也有朋友在評論區提到,代碼可執行部分以IF開頭,但是卻沒有以ENDIF結尾。唯一的解釋,就是在NOT這個include裡,聲明了包含ENDIF語句的宏,并把宏的名稱取名為NOT.
(3) ABAP裡感歎号的用法。
ABAP幫助文檔裡說的很清楚,!作為ABAP裡的轉義字元,能夠告訴ABAP編譯器,!後面緊跟的并不是關鍵字,而是普通的ABAP辨別符。
給出的例子也很清晰,如果有人非要用CHANGING和USING作為形式參數的名稱,隻需要在前面加上感歎号即可。
而如果感歎号後面跟的并不是真的ABAP關鍵字,而是普通的辨別符,那又會如何呢?
答案是,此時感歎号會直接被忽略。看下面的例子,加上感歎号的效果和不加一緻。
(4) 現在我們已經知道了,題目中的!NOT,暗示大家在NOT include裡,還定義了一個名為NOT的變量。
首先我們把謎題裡迷惑人眼球的障眼法全部拿掉。
在有NOT參與的ABAP邏輯判斷語句裡,出現偶數個NOT,相當于一個NOT也未出現過(類似負負得正的原理),出現奇數個NOT,隻相當于出現一個NOT.
人稱“琴中藏劍,劍發琴音”的莫大,憑借這手如夢如幻的劍法,在衡山城外擊殺了嵩山十三太保之一的“大嵩陽手”費彬。即使武功強如費彬,也沒弄看透莫大劍法中的虛招。而親愛的ABAP顧問們,這道謎團中重複的NOT虛招,大家看透了沒?
仔細觀察代碼中所有出現!NOT的地方,按照上述法則去除掉多餘的NOT之後,能夠提取出兩個規律:
- !NOT 前面至少有一個IF,OR或者AND
- !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感謝閱讀。
本文來自雲栖社群合作夥伴“汪子熙”,了解相關資訊可以關注微信公衆号"汪子熙"。