Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

डीप डाइव: सिनात्रा के आंतरिक कामकाज को समझना

सिनात्रा एक रूबी वेब फ्रेमवर्क है।

इसे रेल्स का छोटा भाई माना जाता है...

आइए जानते हैं कि सिनात्रा कैसे काम करता है:

  • जब आप अपने प्रोजेक्ट में सिनात्रा को require करते हैं तो क्या होता है?
  • रूट मिलान कैसे काम करता है?
  • अनुरोध और प्रतिक्रियाएं कैसे प्रोसेस होती हैं?

इतने सारे सवाल, लेकिन समय बहुत कम...

कोई बात नहीं!

मैंने आपके लिए कड़ी मेहनत की है और यह लेख तैयार किया है जहां मैं इन सवालों का जवाब देता हूं ताकि आप तेजी से सीख सकें!

सिनात्रा इनिशियलाइज़ेशन

सब कुछ एक फाइल से शुरू होता है: sinatra.rb।

यह फाइल बस main.rb को require करती है, ज्यादा रोमांचक नहीं है ना?

अब यह और दिलचस्प होता है!

main.rb के अंदर आपको base.rb के लिए एक require मिलेगा और साथ ही विकल्प पार्सिंग (पोर्ट, वातावरण, क्वाइट मोड, आदि) का कोड भी।

सिनात्रा रूबी के स्टैंडर्ड लाइब्रेरी से optparse का उपयोग करता है।

यहां और क्या मिल सकता है?

इस at_exit ब्लॉक पर एक नज़र डालें:

 at_exit { Application.run! if $!.nil? && Application.run? } 

यह कोड का एक टुकड़ा है जो प्रोग्राम समाप्त होने पर चलता है।

होता यह है कि रूबी आपके सभी कोड को पढ़ता है और चूंकि आपके पास कोई लूप, स्लीप या ऐसा कुछ नहीं है, इसलिए आपका प्रोग्राम स्वाभाविक रूप से समाप्त हो जाता है।

...लेकिन समाप्त होने से ठीक पहले at_exit ब्लॉक ट्रिगर हो जाता है!

फिर सिनात्रा कार्यभार संभालता है और अनुरोधों को संभालने के लिए एक वेब सर्वर शुरू करता है।

यहां वह कोड है जो यह करता है:

 begin start_server(handler, server_settings, handler_name, &block) rescue Errno::EADDRINUSE $stderr.puts "== Someone is already performing on port #{port}!" raise end # Part of base.rb `run!` method 

ओह और यहां एक और महत्वपूर्ण चीज़ होती है:

 extend Sinatra::Delegator 

Sinatra::Delegator एक मॉड्यूल है जो सिनात्रा DSL मेथड्स जैसे get, post और set को परिभाषित करता है।

इसीलिए आप यह कर सकते हैं:

 get '/' do puts "Hello World!" end 

सिनात्रा ग्लोबल main ऑब्जेक्ट को इस मॉड्यूल के साथ एक्सटेंड करता है।

अनुरोध और प्रतिक्रिया प्रोसेसिंग

ठीक है, इस बिंदु पर हमारे पास एक रनिंग सर्वर है जो नए कनेक्शन स्वीकार करने के लिए तैयार है।

लेकिन जब एक नया कनेक्शन प्राप्त होता है तो क्या होता है?

खैर, सिनात्रा, रेल्स और अन्य रूबी वेब फ्रेमवर्क की तरह, निचले स्तर की सभी चीजों को संभालने के लिए Rack का उपयोग करता है।

Rack आपके एप्लिकेशन पर एक call मेथड उपलब्ध होने की उम्मीद करता है। यह बस एक ऑब्जेक्ट है जिसे आप Rack को इनिशियलाइज़ करते समय देते हैं।

सिनात्रा के मामले में यह ऑब्जेक्ट Sinatra::Base क्लास है।

यहां वह मेथड है:

 # Rack call interface. def call!(env) @env = env @request = Request.new(env) @response = Response.new invoke { dispatch! } invoke { error_block!(response.status) } unless @env['sinatra.error'] @response.finish end # Modified version of Sinatra's call method (for clarity) 

ऐसा लगता है कि हमें आगे dispatch! मेथड की जांच करने की जरूरत है ताकि यह दिखाया जा सके कि अनुरोध को कैसे संभाला जाता है।

यह रहा वह मेथड:

 def dispatch! invoke do static! if settings.static? && (request.get? || request.head?) filter! :before route! end rescue ::Exception => boom invoke { handle_exception!(boom) } ensure filter! :after unless env['sinatra.static_file'] end # Edited down to the important parts 

अनुरोध 4 चरणों में विभाजित होता है:

  1. स्टैटिक फाइलें पहले चेक की जाती हैं। ये CSS, JS और इमेज जैसी फाइलें होती हैं। यह सेटिंग डिफ़ॉल्ट रूप से सक्षम होती है यदि "public" नामक डायरेक्टरी मौजूद हो
  2. बिफोर फिल्टर चलाया जाता है
  3. रूट मिलान
  4. आफ्टर फिल्टर चलाया जाता है

अब हम प्रत्येक चरण में गहराई से जा सकते हैं कि विस्तार से क्या होता है।

स्टैटिक फाइलें सर्व करना

static! मेथड काफी सरल है:

 def static!(options = {}) return if (public_dir = settings.public_folder).nil? path = File.expand_path("#{public_dir}#{URI_INSTANCE.unescape(request.path_info)}" ) return unless File.file?(path) cache_control(*settings.static_cache_control) if settings.static_cache_control? send_file(path, options) end 

यह कोड चेक करता है कि अनुरोधित फाइल मौजूद है या नहीं, फिर यह "Cache Control" HTTP हेडर सेट करता है।

आखिरी लाइन पर यह send_file को कॉल करता है और यह वही करता है जो नाम कहता है 🙂

बिफोर फिल्टर

एक बिफोर फिल्टर आपको मिलान करने वाले रूट को खोजने का प्रयास करने से पहले कोड चलाने की अनुमति देता है।

एक फिल्टर इस तरह जोड़ा जाता है:

 # Define a before filter. # Runs before all requests within the same context as route handlers # and may access/modify the request and response. @filters = {:before => [], :after => []} def before(path = /.*/, **options, &block) add_filter(:before, path, options, &block) end def after(path = /.*/, **options, &block) add_filter(:after, path, options, &block) end def add_filter(type, path = /.*/, **options, &block) filters[type] << compile!(type, path, block, options) end 

जैसा कि आप देख सकते हैं filters बस दो कुंजियों वाला एक हैश है, प्रत्येक फिल्टर प्रकार के लिए एक।

लेकिन compile! क्या है?

यह मेथड 3 तत्वों के साथ एक सरणी लौटाता है: एक पैटर्न, शर्तों की एक सरणी और एक रैपर।

उसी मेथड का उपयोग रूट्स जनरेट करने के लिए किया जाता है (जब आप get या post ब्लॉक का उपयोग करते हैं):

 def get(path, opts = {}, &block) route('GET', path, opts, &block) end def route(verb, path, options = {}, &block) signature = compile!(verb, path, block, options) (@routes[verb] ||= []) << signature signature end # Methods edited for clarity 

इससे हम सीख सकते हैं कि सिनात्रा फिल्टर व्यवहार और काम रूट्स के समान ही करते हैं।

रूट मिलान

अनुरोध प्रोसेसिंग चक्र में अगला चरण रूट मिलान है:

 def route!(base = settings, pass_block = nil) routes = base.routes[@request.request_method] routes.each do |pattern, conditions, block| process_route(pattern, conditions) route_eval end route_missing end # Edited method 

यह कोड उस रिक्वेस्ट मेथड (get, post, आदि) से मेल खाने वाले हर एक रूट पर पुनरावृति करता है।

रूट मिलान process_route मेथड के अंदर होता है:

 def process_route(pattern, keys, conditions, block = nil, values = []) route = @request.path_info route = '/' if route.empty? and not settings.empty_path_info? return unless match = pattern.match(route) end 

जहां pattern एक रेगुलर एक्सप्रेशन है।

यदि कोई रूट पाथ और शर्तों दोनों से मेल खाता है तो route_eval को कॉल किया जाएगा, जो ब्लॉक (आपके get / post रूट का शरीर) का मूल्यांकन करता है और रूट मिलान प्रक्रिया को समाप्त करता है।

 # Run a route block and throw :halt with the result. def route_eval throw :halt, yield end 

यह असामान्य catch / throw तंत्र का उपयोग फ्लो कंट्रोल के लिए करता है।

मैं इसके खिलाफ सिफारिश करूंगा क्योंकि कोड के फ्लो का पालन करना बहुत भ्रमित करने वाला हो सकता है, लेकिन इस सुविधा का वास्तविक दुनिया का उदाहरण देखना दिलचस्प है।

प्रतिक्रिया निर्माण

अनुरोध चक्र का अंतिम चरण प्रतिक्रिया तैयार करना है।

तो प्रतिक्रिया कहां जाती है?

invoke मेथड इस तरह प्रतिक्रिया एकत्र करता है:

 res = catch(:halt) { yield } 

इस परिणाम को body मेथड का उपयोग करके प्रतिक्रिया बॉडी को असाइन किया जाता है:

 body(res) 

अब अगर हम वहां वापस देखें जहां हमने शुरू किया था, call मेथड, हमें कोड की यह लाइन मिलेगी:

 @response.finish 

यह @response पर finish मेथड को कॉल करता है, जो एक Rack::Response ऑब्जेक्ट है।

दूसरे शब्दों में, यह वास्तव में क्लाइंट को प्रतिक्रिया भेजने को ट्रिगर करेगा।

बोनस: सेट मेथड कैसे काम करता है

सेट मेथड सिनात्रा के DSL (डोमेन-स्पेसिफिक लैंग्वेज) का हिस्सा है और यह आपको अपने सिनात्रा एप्लिकेशन में कहीं भी कॉन्फिगरेशन विकल्प सेट करने देता है।

उदाहरण:

 set :public_folder, '/var/www' 

हर बार जब आप set का उपयोग करते हैं तो सिनात्रा मेटाप्रोग्रामिंग के माध्यम से 3 मेथड्स बनाता है:

 define_singleton("#{option}=", setter) if setter define_singleton(option, getter) if getter define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" 

ये 3 मेथड्स हैं (public_folder उदाहरण के साथ):

  • public_folder
  • public_folder=
  • public_folder?

यह मेथड सेटर मेथड (public_folder=) को भी कॉल करेगा यदि यह पहले से मौजूद है:

 if respond_to?("#{option}=") && !ignore_setter return __send__("#{option}=", value) end 

याद रखें कि मेटाप्रोग्रामिंग मुफ्त नहीं है, इसलिए मैं सिर्फ एक options हैश के साथ रहूंगा। आपको उन फैंसी मेथड्स की आवश्यकता नहीं है।

सारांश

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

इस पोस्ट को अन्य रूबी डेवलपर्स के साथ शेयर करना न भूलें ताकि वे भी इससे सीख सकें 🙂

  1. एक्सेल के डेटा एनालिसिस टूलपैक को केवल दो आसान चरणों में इंस्टॉल करें एक्सेल के डेटा एनालिसिस टूलपैक को केवल दो आसान चरणों में इंस्टॉल करें

    डेटा विश्लेषण एक एक्सेल ऐड-इन प्रोग्राम है जो हमें जटिल सांख्यिकीय और वित्तीय विश्लेषण करने में मदद करता है। इसने सहसंबंध, फूरियर विश्लेषण, मूविंग एवरेज, प्रतिगमन आदि जैसे कई गणितीय संचालन को आसान बना दिया है। डिफ़ॉल्ट रूप से, डेटा विश्लेषण टूलपैक इंस्टॉल नहीं होता है। एक बार जब आप प्लग-इन इंस्टॉल क

  1. एक्सेल का डेटा एनालिसिस टूलपैक इंस्टॉल करें: चरण-दर-चरण गाइड एक्सेल का डेटा एनालिसिस टूलपैक इंस्टॉल करें: चरण-दर-चरण गाइड

    माइक्रोसॉफ्ट एक्सेल का उपयोग विभिन्न प्रकार के डेटा विश्लेषण के लिए बहुत व्यापक रूप से किया जाता है। यदि हम एक जटिल सांख्यिकीय या इंजीनियरिंग विश्लेषण विकसित करना चाहते हैं, तो इसमें समय और मेहनत लगेगी। लेकिन हम एक्सेल में डेटा विश्लेषण विकल्प का उपयोग करके समस्याओं को खत्म कर सकते हैं। लेकिन हम स्व

  1. एंडपॉइंट सुरक्षा समझाया गया: उपकरणों और नेटवर्क की सुरक्षा एंडपॉइंट सुरक्षा समझाया गया: उपकरणों और नेटवर्क की सुरक्षा

    एंडपॉइंट सुरक्षा एक व्यापक शब्द है जिसमें विभिन्न सुरक्षा कार्रवाइयां शामिल हैं, लेकिन यह आमतौर पर नेटवर्क सुरक्षा से जुड़ा होता है। एंडपॉइंट सुरक्षा, जिसे आमतौर पर एंडपॉइंट प्रोटेक्शन के रूप में जाना जाता है, एक कंपनी के नेटवर्क को वायरलेस, रिमोट, या मोबाइल गैजेट्स जैसे टैबलेट, लैपटॉप, और स्मार्टफो