2015-12-01 11 views
7

MongoDB driver के लिए एक पैकेज में, मुझे एक अद्वितीय दस्तावेज़ आईडी उत्पन्न करने के लिए एक फ़ंक्शन की आवश्यकता थी।erlang: अब() v18 में बहिष्कृत, सबसे अच्छा संक्रमण क्या है

इस समारोह :erlang.now() कि v18

मैं कैसे विस्थापित लेकिन कोई सफलता के लिए पर मदद के लिए देखो में पदावनत किया गया है का उपयोग करता है।

मेरे वास्तविक कोड (छोटा):

defmodule MyModule_v17 do 
    use Bitwise, only_operators: true 
    def gen_trans_prefix do 
    {gs, s, ms} = :erlang.now 
    (gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655 
    end 
end 

सबसे अच्छा मैं के साथ आया था:

defmodule MyModule_v18 do 
    use Bitwise, only_operators: true 
    Kernel.if Keyword.get(:erlang.module_info, :exports) |> Enum.any?(fn({:system_time, 1}) -> true; (_) -> false end) do 
    def gen_trans_prefix do 
     :erlang.system_time(:micro_seconds) &&& 281474976710655 
    end 
    else 
    def gen_trans_prefix do 
     {gs, s, ms} = :erlang.now 
     (gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655 
    end 
    end 
end 

यह काम करता है, लेकिन मैं इसे सबसे अच्छा तरीका है नहीं लग रहा है।

कोई सुझाव?

उत्तर

6

एक ही समय में ओटीपी 17 और 18 (और उससे परे) दोनों का समर्थन करने के लिए, आपको संकलन समय पर ओटीपी संस्करण का पता लगाने की आवश्यकता होगी।

{erl_opts, [ 
    {platform_define, "(?=^[0-9]+)(?!^17$)", time_correction} 
]}. 

यह नियमित अभिव्यक्ति की जांच से काम करता है क्योंकि OTP 17 की रिहाई semantic versioning के उपयोग में चिह्नित (या के पास), तो कुछ भी OTP 17 से कम एक संस्करण संख्या है कि शुरू होता है: यहाँ rebar.config for the lftpc project से एक उदाहरण है आर के साथ (आर 16 की तरह)।

फिर, अपने Erlang कोड में आप this की तरह कुछ कर सकते हैं:

def erlc_options do 
    extra_options = try do 
    case :erlang.list_to_integer(:erlang.system_info(:otp_release)) do 
     v when v >= 18 -> 
     [{:d, :time_correction}] 
     _ -> 
     [] 
    end 
    catch 
    _ -> 
     [] 
    end 
    extra_options 
end 

:

-ifdef(time_correction). 
gen_trans_prefix() -> 
    {GS, S, MS} = erlang:timestamp(), 
    (GS * 1000000000000 + S * 1000000 + MS) band 281474976710655. 
-else. 
gen_trans_prefix() -> 
    {GS, S, MS} = erlang:now(), 
    (GS * 1000000000000 + S * 1000000 + MS) band 281474976710655. 
-endif. 

आप मिश्रण का उपयोग कर रहे हैं, तो आप erlc_options रूप mix.exs for the jose project में किया परिभाषित कर सकते हैं erlc_options को परियोजना के लिए एर्लांग या एलिक्सीर कोड द्वारा संदर्भित किया जा सकता है (आपके प्रश्न में उल्लिखित समाधान के समान):

defmodule MyModule do 
    use Bitwise, only_operators: true 
    if Enum.member?(Mix.Project.get!.project[:erlc_options] || [], {:d, :time_correction}) do 
    def gen_trans_prefix do 
     {gs, s, ms} = :erlang.timestamp 
     (gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655 
    end 
    else 
    def gen_trans_prefix do 
     {gs, s, ms} = :erlang.now 
     (gs * 1000000000000 + s * 1000000 + ms) &&& 281474976710655 
    end 
    end 
end 
+0

आपकी पोस्ट के लिए धन्यवाद, मुझे जिस तरह से आपने इसे संभाला है उसे पसंद है। मैं एक रेपो [jerp/now] (https://github.com/jerp/now) बनाता हूं जहां मैंने अंत में जो किया वह मैंने किया। यह आपके उत्तर के करीब है – jerome

+0

इसके अलावा, एक और मामले पर, मुझे एर्लांग-जोस के बारे में पता लगाना अच्छा लगता है। मैं ओपनएसएसएल पर एक बंदरगाह का उपयोग कर साइन संदेश करता हूं, मैं निकट भविष्य में आपकी परियोजना को देखूंगा। – jerome

1

इस प्रयास करें:

erlang:timestamp() 

जो erlang लिए एक विकल्प है: अब() erlang में 18

जाँच करें: http://www.erlang.org/doc/man/erlang.html#timestamp-0

+0

धन्यवाद लेकिन सवाल यह है कि erlang.now() लेकिन क्या एक पैकेज है कि दोनों संस्करण v17 और v18 में काम करना चाहिए के लिए सबसे अच्छा संक्रमण है को बदलने के लिए नहीं है। 'erlang: tim17amp()' v17 – jerome

+0

में मौजूद नहीं है, वैसे भी यह एक उपयुक्त प्रतिस्थापन नहीं है, जैसा कि erlang: timestamp/0 erlang की तरह अद्वितीय होने की गारंटी नहीं है: अब/0, प्रश्न की एक महत्वपूर्ण विशेषता है। – Michael

2

हैं erlang:now()बहिष्कृत है नहीं बल्कि हटाया Erlang 18 में तो मैं अकेले कोड छोड़ दूंगा।

यह मेरा तर्क है: यदि आप नया कोड बनाते हैं, तो इसे 18 और बाद में एरलांग के लिए बनाएं और erlang:timestamp() का उपयोग करें। यही है, अगर आप नया कोड बनाते हैं तो क्या आपको इसे एरलांग 17 और एरलांग 18 दोनों पर चलाने में सक्षम होना चाहिए? संभावना है कि यह नया कोड है, आप केवल यह निर्धारित कर सकते हैं कि यह केवल 18 पर चलता है। और यदि आप कोड बनाए रखते हैं और erlang:now() अभी भी 18 में काम करता है, तो समस्या क्या है?

याद रखें कि बहिष्कृत हटाए गए जैसा नहीं है। इसका मतलब है कि आपको इसे नए काम के लिए इस्तेमाल करने से बचना चाहिए।

+1

खैर, हालांकि यह एक बहुत ही उचित विकल्प है, मुझे एक एपिडर्मिक प्रतिक्रिया मिलती है जब मुझे 'चेतावनी एरलांग दिखाई देता है: अब/0 बीआईएफ को हटा दिया गया है। मुझे लगता है कि इस पुस्तकालय का उपयोग करने वाला कोई भी वही महसूस करेगा। विशेष रूप से जब बोल्ड में कह रहे एरलांग दस्तावेज़ पर देख रहे हैं ** यह फ़ंक्शन बहिष्कृत है! इसका उपयोग न करें! ** – jerome

7

यह पहले से ही "Time and Time Correction in Erlang" documentation में और "Time Goes On" postscript में अद्भुत "Learn You Some Erlang" book पर भी शामिल है।

+0

पॉइंटर स्टीव के लिए धन्यवाद। –

+0

वास्तव में महान संदर्भ। यह मदद करता है। लेकिन सवाल संक्रमण के प्रबंधन के बारे में और अधिक था। "आप कुछ Erlang जानें" में, लेखक [okeuday/uuid] (https://github.com/okeuday/uuid) को इंगित करता है जो @potatosalad के समान समाधान लागू करता है। अभी दोनों विकल्पों को देख रहे हैं। – jerome

संबंधित मुद्दे

 संबंधित मुद्दे