ফাইল.এক্সপ্যান্ড_পাথ ("../..// জেমফিল", __FILE__) এটি কীভাবে কাজ করে? ফাইলটি কোথায়?


84

ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)

আমি কিছু ডিরেক্টরি থেকে একটি .rb ফাইল অ্যাক্সেস করার চেষ্টা করছি এবং একটি টিউটোরিয়াল আমাকে এই কোডটি ব্যবহার করতে বলছে তবে আমি দেখতে পাচ্ছি না যে এটি রত্ন ফাইলটি কীভাবে সন্ধান করছে।


উত্তর:


195
File.expand_path('../../Gemfile', __FILE__)

আপনি যখন বর্তমান ফাইলের সাথে সম্পর্কিত পথটি জানেন তখন কোনও ফাইলের পরম পাথ পাওয়ার জন্য কিছুটা কুৎসিত রুবি আইডিয়াম। এটি লেখার আর একটি উপায় হ'ল:

File.expand_path('../Gemfile', File.dirname(__FILE__))

উভয়ই কুরুচিপূর্ণ তবে প্রথম রূপটি সংক্ষিপ্ত। প্রথম বৈকল্পিকটি তবে এটির হ্যাং না পাওয়া পর্যন্ত খুব অ-স্বজ্ঞাত। অতিরিক্ত কেন ..? (তবে দ্বিতীয় রূপটি কেন এটি প্রয়োজন তা সম্পর্কে একটি ধারণা দিতে পারে)।

এটি এইভাবে কীভাবে কাজ করে: File.expand_pathদ্বিতীয় তর্কটির সাথে সম্পর্কিত (যা বর্তমান কার্যকরী ডিরেক্টরিতে ডিফল্ট হয়) প্রথম আর্গুমেন্টের পরম পথ ফেরায়। __FILE__কোডটি যে ফাইলটিতে রয়েছে সেটির পাথ। যেহেতু এই ক্ষেত্রে দ্বিতীয় যুক্তিটি কোনও ফাইলের পাথ এবং File.expand_pathএকটি ডিরেক্টরি অনুমান করে, ..সঠিক পথটি পেতে আমাদের একটি অতিরিক্ত পথ আটকে থাকতে হবে। এটা এভাবে কাজ করে:

File.expand_pathমূলত এই মত বাস্তবায়িত হয় (নিম্নলিখিত কোডে pathমান থাকবে ../../Gemfileএবং relative_toমান থাকবে /path/to/file.rb):

def File.expand_path(path, relative_to=Dir.getwd)
  # first the two arguments are concatenated, with the second argument first
  absolute_path = File.join(relative_to, path)
  while absolute_path.include?('..')
    # remove the first occurrence of /<something>/..
    absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '')
  end
  absolute_path
end

(এটির সাথে আরও কিছুটা আছে, এটি ~বাড়ির ডিরেক্টরিতে প্রসারিত হয় এবং আরও কিছু - সম্ভবত উপরের কোডটি সহ আরও কিছু সমস্যা রয়েছে)

উপরের কোডটিতে কল করার মাধ্যমে পদক্ষেপটি absolute_pathপ্রথমে মানটি পাবে /path/to/file.rb/../../Gemfile, তারপরে লুপের প্রতিটি রাউন্ডের জন্য প্রথমটি ..সরানো হবে, তার আগে পথের উপাদানটি সহ। প্রথমে /file.rb/..সরানো হয়, তারপরে পরবর্তী রাউন্ডে /to/..সরানো হয়, এবং আমরা পাই /path/Gemfile

একটি দীর্ঘ গল্প সংক্ষিপ্ত করার জন্য, File.expand_path('../../Gemfile', __FILE__)আপনি যখন বর্তমান ফাইলের সাথে সম্পর্কিত পথটি জানেন তখন কোনও ফাইলের পরম পথ পাওয়ার কৌশল trick ..আপেক্ষিক পথে অতিরিক্ত হ'ল ফাইলটির নামটি মুছে ফেলা __FILE__

রুবি ২.০-তে একটি Kernelফাংশন রয়েছে যা __dir__হিসাবে প্রয়োগ করা হয় File.dirname(File.realpath(__FILE__))


4
প্রাক রুবি ১.৯.২ এর সাথে অসম্পূর্ণতা ছাড়া আপনার কেবল 'প্রয়োজনীয়_সম্পর্কিত' ব্যবহার করা উচিত নয় এমন কোনও কারণ আছে কি?
ড্যানি অ্যান্ড্রুজ

9
রুবি ২.০ হিসাবে আপনি ব্যবহার করতে পারেনFile.expand_path('../Gemfile',__dir__)
ফ্রোগজ

থিওর এই লাইনটি কোনও ডিরেক্টরি না File.expand_path assumes a directoryহলেও অবশেষে এটি আমার জন্য ক্লিক করতে পেল __FILE__। জিনিসগুলি ব্যবহার করার জন্য __dir__যা আসলে একটি ডিরেক্টরি।
এমবিগ্রাস

9

দুটি উল্লেখ:

  1. ফাইল :: প্রসারিত_পথ পদ্ধতি ডকুমেন্টেশন
  2. কিভাবে __FILE__রুবি কাজ করে

আমি আজ এই জুড়ে হোঁচট খেয়েছি:

বুট.আরবি রিয়েল গিথুবে প্রতিশ্রুতিবদ্ধ

ডিরেক্টরি ট্রিতে আপনি boot.rb থেকে দুটি ডিরেক্টরিতে যান:

/ রেলটি / লিব / রেল / জেনারেটর / রেল / অ্যাপ / টেম্পলেট

আপনি জেমফাইল দেখেন, যা আমাকে বিশ্বাস করতে পরিচালিত করে যে File.expand_path("../../Gemfile", __FILE__)নিম্নলিখিত ফাইলটি উল্লেখ করেছে:/path/to/this/file/../../Gemfile


পোস্টটির জন্য ধন্যবাদ, তবে এটি জেমবন্ডার টিউটোরিয়াল থেকে এসেছে সুতরাং আমি কীভাবে তাদের এটি ছিল তা বুঝতে চেষ্টা করছিলাম :)
ততদিনে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.