রুবিতে অ্যারে স্লাইসিং: অযৌক্তিক আচরণের জন্য ব্যাখ্যা (রুবিকানস ডটকম থেকে নেওয়া)


232

আমি রুবি কোয়ানসে অনুশীলনের মধ্য দিয়ে যাচ্ছিলাম এবং আমি নীচের রুবি কিরক দ্বারা আক্রান্ত হয়েছি যে আমি সত্যিই অবর্ণনীয় বলে মনে করেছি:

array = [:peanut, :butter, :and, :jelly]

array[0]     #=> :peanut    #OK!
array[0,1]   #=> [:peanut]  #OK!
array[0,2]   #=> [:peanut, :butter]  #OK!
array[0,0]   #=> []    #OK!
array[2]     #=> :and  #OK!
array[2,2]   #=> [:and, :jelly]  #OK!
array[2,20]  #=> [:and, :jelly]  #OK!
array[4]     #=> nil  #OK!
array[4,0]   #=> []   #HUH??  Why's that?
array[4,100] #=> []   #Still HUH, but consistent with previous one
array[5]     #=> nil  #consistent with array[4] #=> nil  
array[5,0]   #=> nil  #WOW.  Now I don't understand anything anymore...

তাহলে কেন array[5,0]সমান নয় array[4,0]? আপনি যখন (দৈর্ঘ্য + 1) তম অবস্থান থেকে শুরু করবেন তখন অ্যারে স্লাইসিং এই অদ্ভুত আচরণ করার কোনও কারণ আছে কি ??



দেখে মনে হচ্ছে প্রথম সংখ্যাটি সূচকটি শুরু হবে, দ্বিতীয় সংখ্যাটি কতগুলি উপাদানকে টুকরো টুকরো করতে হবে
অস্টিন

উত্তর:


185

স্লাইসিং এবং ইনডেক্সিং দুটি পৃথক ক্রিয়াকলাপ এবং অন্যটির থেকে অন্যের আচরণের অনুমান করা যেখানে আপনার সমস্যা রয়েছে।

স্লাইসে প্রথম যুক্তি উপাদানটিকে নয় তবে উপাদানগুলির মধ্যে স্থানগুলি চিহ্নিত করে, স্প্যানগুলি সংজ্ঞায়িত করে (এবং উপাদানগুলি নিজেরাই নয়):

  :peanut   :butter   :and   :jelly
0         1         2      3        4

4 এখনও অ্যারের মধ্যে রয়েছে, সবেমাত্র; আপনি যদি 0 টি উপাদানকে অনুরোধ করেন তবে আপনি অ্যারের খালি প্রান্তটি পাবেন। তবে 5 সূচি নেই, তাই আপনি সেখান থেকে স্লাইস করতে পারবেন না।

আপনি যখন array[4]সূচকগুলি করেন (যেমন ), আপনি নিজেরাই উপাদানগুলিতে ইশারা করছেন, সুতরাং সূচকগুলি কেবল 0 থেকে 3 পর্যন্ত চলে।


8
উত্স দ্বারা ব্যাক আপ না করা ভাল ধারণা। অপ্রয়োজনীয় না হয়ে, আমি ওপি এবং অন্যান্য মন্তব্যকারীদের মতো "কেন" ব্যাখ্যা করতে চাইলে কোনও লিঙ্কে আগ্রহী। আপনার চিত্রটি অ্যারে [4] শূন্য ব্যতীত অন্যায় করে তোলে। অ্যারে [3] হ'ল: জেলি। আমি আশা করব অ্যারে [4, এন] শূন্য হবে তবে এটি [] ওপি বলেছে। যদি এটি কোনও জায়গা হয় তবে এটি একটি দুর্দান্ত অকেজো জায়গা কারণ অ্যারে [4, -1] শূন্য। সুতরাং আপনি অ্যারে [4] এর সাথে কিছুই করতে পারবেন না।
স্কোয়ারিজম

5
@ সিকিউরিজম আমি সবেমাত্র চার্লস অলিভার নিউটারের (টুইটারে হেইডিয়াস) কাছ থেকে নিশ্চিত হয়েছি যে এটি সঠিক ব্যাখ্যা। তিনি বড় সময়ের জেআরবি দেব, তাই আমি তাঁর শব্দটিকে বেশ প্রামাণিক বলে বিবেচনা করব।
হ্যাঙ্ক গে

18
নীচে এই আচরণের ন্যায্যতা রয়েছে: ব্লেড.নাগোকাট.এক.জেপ
ম্যাট ব্রায়ানন

4
সঠিক ব্যাখ্যা। রুবি-কোর সম্পর্কে একই আলোচনা: redmine.ruby-lang.org/issues/4245 , redmine.ruby-lang.org/issues/4541
মার্ক-আন্দ্রে লাফোর্টুন

18
"বেড়া পোস্টিং" হিসাবেও উল্লেখ করা হয়। পঞ্চম বেড়া-পোস্ট (আইডি 4) বিদ্যমান, তবে পঞ্চম উপাদানটি নেই। স্লাইসিং একটি বেড়া-পোস্ট অপারেশন, সূচক একটি উপাদান অপারেশন।
ম্যাটিটি কে

27

এই স্লাইস অ্যারে থেকে একটি অ্যারে, প্রাসঙ্গিক উত্স ডকুমেন্টেশন ফিরে আসে এই সত্যটি সাথে করতে হবে # স্লাইস:

 *  call-seq:
 *     array[index]                -> obj      or nil
 *     array[start, length]        -> an_array or nil
 *     array[range]                -> an_array or nil
 *     array.slice(index)          -> obj      or nil
 *     array.slice(start, length)  -> an_array or nil
 *     array.slice(range)          -> an_array or nil

যা আমাকে পরামর্শ দেয় যে আপনি যদি শুরুটি সীমা ছাড়িয়ে যান তবে তা শূন্য হয়ে যাবে, সুতরাং আপনার উদাহরণে array[4,0]4 র্থ উপাদান রয়েছে যা জিজ্ঞাসা করে, তবে শূন্য উপাদানগুলির একটি অ্যারে ফিরে আসতে বলে। array[5,0]সীমা ছাড়িয়ে একটি সূচক জিজ্ঞাসা করার সময় এটি শূন্য করে returns এটি সম্ভবত আরও বোধগম্য হয় যদি আপনি মনে করেন যে স্লাইস পদ্ধতিটি মূল ডেটা কাঠামোটি পরিবর্তন না করে একটি নতুন অ্যারে ফিরছে ।

সম্পাদনা করুন:

মন্তব্যগুলি পর্যালোচনা করার পরে আমি এই উত্তরটি সম্পাদনা করার সিদ্ধান্ত নিয়েছি। আর্গ মান দুটি হলে স্লাইস নিম্নলিখিত কোড স্নিপেট কল করে :

if (argc == 2) {
    if (SYMBOL_P(argv[0])) {
        rb_raise(rb_eTypeError, "Symbol as array index");
    }
    beg = NUM2LONG(argv[0]);
    len = NUM2LONG(argv[1]);
    if (beg < 0) {
        beg += RARRAY(ary)->len;
    }
    return rb_ary_subseq(ary, beg, len);
}

আপনি যদি array.cশ্রেণীর দিকে তাকান যেখানে rb_ary_subseqপদ্ধতিটি সংজ্ঞায়িত হয়েছে, আপনি দেখতে পাচ্ছেন যে এটি দৈর্ঘ্য সীমা ছাড়িয়ে থাকলে সূচকটি নয়:

if (beg > RARRAY_LEN(ary)) return Qnil;

এই ক্ষেত্রে এটি যা ঘটছে যখন 4 টি পাস করা হয়, এটি পরীক্ষা করে যে সেখানে 4 টি উপাদান রয়েছে এবং এটি শূন্য রিটার্নকে ট্রিগার করে না। এটি পরে যায় এবং দ্বিতীয় আরগটি শূন্যতে সেট করা থাকলে একটি খালি অ্যারে প্রদান করে ray যদি 5টি পাস করা হয় তবে অ্যারেতে 5 টি উপাদান নেই, তাই শূন্য আরগের মূল্যায়ন হওয়ার আগে এটি শূন্য করে। কোড এখানে লাইন 944 এ।

আমি এটি একটি বাগ হিসাবে বিশ্বাস করি, বা কমপক্ষে অপ্রত্যাশিত এবং 'সর্বনিম্ন অবাকের নীতি' নয়। আমি যখন কয়েক মিনিট পাব আমি রুবি কোরতে কমপক্ষে একটি ব্যর্থ পরীক্ষা প্যাচ জমা দেব।


2
তবে ... অ্যারেতে 4 দ্বারা নির্দেশিত উপাদান [4,0] এরও অস্তিত্ব নেই ... - কারণ এটি আসলে 5 তম উপাদান (0 ভিত্তিক গণনা, উদাহরণগুলি দেখুন)। সুতরাং এটি পাশাপাশি গণ্ডি বাইরে।
পাস্কাল ভ্যান হেক্ক

1
তুমি ঠিক বলছো. আমি ফিরে গিয়ে উত্সটির দিকে তাকালাম এবং দেখে মনে হচ্ছে যে প্রথম যুক্তিটি সি কোডের ভিতরে দৈর্ঘ্য হিসাবে পরিচালনা করা হয়, সূচি নয়। আমি আমার উত্তর সম্পাদনা করব, এটি প্রতিফলিত করতে। আমি মনে করি এটি একটি বাগ হিসাবে জমা দেওয়া যেতে পারে।
জেদ স্নাইডার

23

কমপক্ষে নোট করুন যে আচরণটি সামঞ্জস্যপূর্ণ। 5 থেকে আপ পর্যন্ত সমস্ত কিছু একই কাজ করে; অদ্ভুততা কেবল তখনই ঘটে [4,N]

হতে পারে এই প্যাটার্নটি সাহায্য করে, বা সম্ভবত আমি কেবল ক্লান্ত হয়ে পড়েছি এবং এটি কোনওভাবেই সহায়তা করে না।

array[0,4] => [:peanut, :butter, :and, :jelly]
array[1,3] => [:butter, :and, :jelly]
array[2,2] => [:and, :jelly]
array[3,1] => [:jelly]
array[4,0] => []

[4,0], আমরা অ্যারের শেষটি ধরি catch শেষেরটি যদি ফিরে আসে তবে প্রকৃতপক্ষে সৌন্দর্যে যতটা নিদর্শন রয়েছে, আমি আসলে এটি দেখতে পেয়েছি nil। এর মতো প্রসঙ্গে, 4প্রথম প্যারামিটারের জন্য একটি গ্রহণযোগ্য বিকল্প যাতে খালি অ্যারেটি ফিরে পাওয়া যায়। একবার আমরা 5 এবং উপরে আঘাত করি, তবে পদ্ধতিটি পুরোপুরি সীমা ছাড়িয়ে যাওয়ার প্রকৃতির দ্বারা তাত্ক্ষণিকভাবে প্রস্থান করে।


12

আপনি যখন অ্যারের চেয়ে স্লাইস বিবেচনা করেন তখন এটি কোনও বৈধ লভ্যালু হতে পারে, এটি কেবলমাত্র মূল্যবোধ নয়:

array = [:peanut, :butter, :and, :jelly]
# replace 0 elements starting at index 5 (insert at end or array):
array[4,0] = [:sandwich]
# replace 0 elements starting at index 0 (insert at head of array):
array[0,0] = [:make, :me, :a]
# array is [:make, :me, :a, :peanut, :butter, :and, :jelly, :sandwich]

# this is just like replacing existing elements:
array[3, 4] = [:grilled, :cheese]
# array is [:make, :me, :a, :grilled, :cheese, :sandwich]

পরিবর্তে array[4,0]ফিরে আসলে এটি সম্ভব হবে না । যাইহোক, আয়গুলি সীমার বাইরে থাকার কারণে (4-এলিমেন্ট অ্যারের 4 র্থ উপাদানটি সন্নিবেশ করা অর্থপূর্ণ তবে 4 এলিমেন্ট অ্যারের 5 ম এলিমেন্টের পরে সন্নিবেশ করানো হয় না) returnsnil[]array[5,0]nil

স্লাইস সিনট্যাক্সটি array[x,y]" xউপাদানগুলির মধ্যে শুরু arrayকরে, yউপাদান পর্যন্ত নির্বাচন করুন " হিসাবে পড়ুন । arrayকমপক্ষে xউপাদান থাকলে এটি কেবল অর্থবোধক ।


11

এটি বোঝা যায় না

আপনাকে সেই টুকরোগুলি বরাদ্দ করতে সক্ষম হতে হবে, সুতরাং সেগুলি এমনভাবে সংজ্ঞায়িত করা হয় যে স্ট্রিংয়ের শুরু এবং শেষের শূন্য-দৈর্ঘ্যের এক্সপ্রেশনগুলি কাজ করে।

array[4, 0] = :sandwich
array[0, 0] = :crunchy
=> [:crunchy, :peanut, :butter, :and, :jelly, :sandwich]

1
আপনি যে স্লাইসটি শূন্য হিসাবে ফিরে আসে এমন পরিসীমাটিকেও বরাদ্দ করতে পারেন, সুতরাং এই ব্যাখ্যাটি প্রসারিত করা কার্যকর হবে। array[5,0]=:foo # array is now [:peanut, :butter, :and, :jelly, nil, :foo]
এমফাজেকাস

নির্ধারিত হওয়ার সময় দ্বিতীয় সংখ্যাটি কী করবে? এটি উপেক্ষা করা হবে বলে মনে হচ্ছে। [26] pry(main)> array[4,5] = [:love, :hope, :peace] => [:peanut, :butter, :and, :jelly, :love, :hope, :peace]
ড্রিউ ভার্লি

@ ড্র্রুভারলি এটি উপেক্ষা করা হয় না :array = [:a, :b, :c, :d, :e]; array[1,2] = :x, :x; array => [:a, :x, :x, :d, :e]
ফ্যানউজেন

10

আমি গ্যারি রাইটের ব্যাখ্যাও খুব সহায়ক হিসাবে পেয়েছি। http://www.ruby-forum.com/topic/1393096#990065

গ্যারি রাইটের উত্তরটি হ'ল -

http://www.ruby-doc.org/core/classes/Array.html

দস্তাবেজগুলি অবশ্যই আরও স্পষ্ট হতে পারে তবে আসল আচরণটি স্বনির্ভর এবং কার্যকর useful দ্রষ্টব্য: আমি স্ট্রিংয়ের 1.9.X সংস্করণ ধরে নিচ্ছি।

এটি নিম্নলিখিত পদ্ধতিতে নম্বর বিবেচনা করতে সহায়তা করে:

  -4  -3  -2  -1    <-- numbering for single argument indexing
   0   1   2   3
 +---+---+---+---+
 | a | b | c | d |
 +---+---+---+---+
 0   1   2   3   4  <-- numbering for two argument indexing or start of range
-4  -3  -2  -1

সাধারণ (এবং বোধগম্য) ভুলটি খুব ধরে নেওয়া হয় যে একক যুক্তি সূচকের শব্দার্থক দুটি আর্গুমেন্টের দৃশ্যে (বা ব্যাপ্তি) প্রথম আর্গুমেন্টের শব্দার্থক হিসাবে একই । তারা বাস্তবে একই জিনিস নয় এবং ডকুমেন্টেশনগুলি এটি প্রতিফলিত করে না। ত্রুটিটি অবশ্যই ডকুমেন্টেশনে রয়েছে এবং প্রয়োগের ক্ষেত্রে নয়:

একক যুক্তি: সূচক স্ট্রিংয়ের মধ্যে একটি একক অক্ষরের অবস্থান উপস্থাপন করে। ফলাফলটি হ'ল সূচকটিতে পাওয়া একক অক্ষরের স্ট্রিং বা শূন্যতার কারণ প্রদত্ত সূচকে কোনও অক্ষর নেই।

  s = ""
  s[0]    # nil because no character at that position

  s = "abcd"
  s[0]    # "a"
  s[-4]   # "a"
  s[-5]   # nil, no characters before the first one

দুটি পূর্ণসংখ্যার যুক্তি: আর্গুমেন্টগুলি নিষ্কাশন করতে বা প্রতিস্থাপন করার জন্য স্ট্রিংয়ের একটি অংশ সনাক্ত করে। বিশেষত, স্ট্রিংয়ের শূন্য-প্রস্থের অংশগুলিও চিহ্নিত করা যায় যাতে স্ট্রিংয়ের সামনের বা শেষের অংশ সহ বিদ্যমান অক্ষরগুলির আগে বা পরে পাঠ্য সন্নিবেশ করা যায়। এই ক্ষেত্রে, প্রথম যুক্তি একটি চরিত্রের অবস্থান চিহ্নিত করে না বরং পরিবর্তে উপরের চিত্রের মতো বর্ণের মধ্যে স্থান চিহ্নিত করে। দ্বিতীয় যুক্তি দৈর্ঘ্য, যা 0 হতে পারে।

s = "abcd"   # each example below assumes s is reset to "abcd"

To insert text before 'a':   s[0,0] = "X"           #  "Xabcd"
To insert text after 'd':    s[4,0] = "Z"           #  "abcdZ"
To replace first two characters: s[0,2] = "AB"      #  "ABcd"
To replace last two characters:  s[-2,2] = "CD"     #  "abCD"
To replace middle two characters: s[1..3] = "XX"    #  "aXXd"

একটি পরিসীমা আচরণ বেশ আকর্ষণীয়। প্রারম্ভিক পয়েন্টটি প্রথম আর্গুমেন্টের সমান যখন দুটি আর্গুমেন্ট সরবরাহ করা হয় (উপরে বর্ণিত হিসাবে) তবে পরিসরের শেষ বিন্দুটি 'একক অক্ষর' বা দুটি সংখ্যার আর্গুমেন্টের সাথে "প্রান্তের অবস্থান" হিসাবে অক্ষরের অবস্থান হতে পারে। পার্থক্যটি ডাবল-ডট পরিসর বা ট্রিপল-ডট পরিসর ব্যবহৃত হয় কিনা তা দ্বারা নির্ধারিত হয়:

s = "abcd"
s[1..1]           # "b"
s[1..1] = "X"     # "aXcd"

s[1...1]          # ""
s[1...1] = "X"    # "aXbcd", the range specifies a zero-width portion of
the string

s[1..3]           # "bcd"
s[1..3] = "X"     # "aX",  positions 1, 2, and 3 are replaced.

s[1...3]          # "bc"
s[1...3] = "X"    # "aXd", positions 1, 2, but not quite 3 are replaced.

আপনি যদি এই উদাহরণগুলির মধ্যে ফিরে যান এবং জোর করে এবং ডাবল বা সীমা সূচক উদাহরণগুলির জন্য একক সূচক শব্দার্থ ব্যবহার করেন তবে আপনি কেবল বিভ্রান্ত হবেন। আসকি আচরণের মডেল করার জন্য আপনি ascii ডায়াগ্রামে প্রদর্শিত বিকল্প নম্বরটি ব্যবহার করতে পারেন।


3
আপনি কি এই থ্রেডের মূল ধারণাটি অন্তর্ভুক্ত করতে পারেন? (লিঙ্কটির ক্ষেত্রে একদিন অবৈধ হয়ে যায়)
ভোনসি

8

আমি সম্মত হই যে এটি আশ্চর্যজনক আচরণের মতো বলে মনে হচ্ছে, তবে এমনকি সরকারী দস্তাবেজগুলিArray#slice নীচের "বিশেষ ক্ষেত্রে" আপনার উদাহরণের মতো একই আচরণ প্রদর্শন করে:

   a = [ "a", "b", "c", "d", "e" ]
   a[2] +  a[0] + a[1]    #=> "cab"
   a[6]                   #=> nil
   a[1, 2]                #=> [ "b", "c" ]
   a[1..3]                #=> [ "b", "c", "d" ]
   a[4..7]                #=> [ "e" ]
   a[6..10]               #=> nil
   a[-3, 3]               #=> [ "c", "d", "e" ]
   # special cases
   a[5]                   #=> nil
   a[5, 1]                #=> []
   a[5..10]               #=> []

দুর্ভাগ্যক্রমে, তাদের বিবরণ এমনকি এটি কেন এইভাবে কাজ করে সে Array#sliceসম্পর্কে কোনও অন্তর্দৃষ্টি দেয় না বলে মনে হয় :

এলিমেন্ট রেফারেন্স index সূচকে উপাদানটি ফেরত দেয় , বা শুরুতে এবং দৈর্ঘ্যের উপাদানগুলির জন্য অবিরত একটি সাবহারিকে প্রদান করে বা ব্যাপ্তি দ্বারা নির্দিষ্ট করা সাববারিকে প্রদান করে । নেতিবাচক সূচকগুলি অ্যারের শেষ থেকে পিছনে গণনা করে (-1 শেষ উপাদানটি হয়)। সূচক (বা সূচনা সূচনা) সীমা ছাড়িয়ে থাকলে শূন্য দেয়।


7

জিম ওয়েইরিচ প্রদত্ত একটি ব্যাখ্যা

এটি সম্পর্কে চিন্তা করার এক উপায় হ'ল সূচি পজিশন 4 অ্যারের একেবারে প্রান্তে। একটি স্লাইস জিজ্ঞাসা করার সময়, আপনি যে পরিমাণ অ্যারে ফেলে রেখেছেন তার যতটা ফিরিয়ে দেন। সুতরাং অ্যারে [2,10], অ্যারে [3,10] এবং অ্যারে [4,10] বিবেচনা করুন ... প্রতিটি অ্যারের শেষের অবশিষ্ট বিটগুলি যথাক্রমে 2 টি উপাদান, 1 টি উপাদান এবং 0 টি উপাদান প্রদান করে। তবে, অবস্থান 5 স্পষ্টভাবে অ্যারের বাইরে এবং প্রান্তে নয়, সুতরাং অ্যারে [5,10] শূন্য করে।


6

নিম্নলিখিত অ্যারে বিবেচনা করুন:

>> array=["a","b","c"]
=> ["a", "b", "c"]

আপনি একটি আইটেমিকে বরাদ্দ করে অ্যারের শুরুতে (মাথা) সন্নিবেশ করতে পারেন a[0,0]"a"এবং এর মধ্যে উপাদানটি রাখার "b"জন্য a[1,0]। মূলত, স্বরলিপিটিতে a[i,n], iএকটি সূচক এবং nবিভিন্ন উপাদানকে উপস্থাপন করে। কখন n=0, এটি অ্যারের উপাদানগুলির মধ্যে অবস্থান নির্ধারণ করে।

এখন আপনি যদি অ্যারের সমাপ্তি সম্পর্কে চিন্তা করেন, আপনি উপরে বর্ণিত স্বরলিপিটি ব্যবহার করে কীভাবে কোনও আইটেমের শেষের দিকে যুক্ত করতে পারেন? সহজ, মান নির্ধারণ করুন a[3,0]। এটি অ্যারের লেজ।

সুতরাং, আপনি যদি উপাদানটিতে অ্যাক্সেস করার চেষ্টা করেন তবে আপনি a[3,0]পাবেন []। এই ক্ষেত্রে আপনি এখনও অ্যারের সীমার মধ্যে রয়েছেন। তবে আপনি যদি অ্যাক্সেস করার চেষ্টা করেন তবে আপনি রিটার্ন মান হিসাবে a[4,0]পাবেন nil, যেহেতু আপনি আর অ্যারের সীমার মধ্যে নন।

এটি সম্পর্কে আরও পড়ুন http://mybrainstormings.wordpress.com/2012/09/10/arrays-in-ruby/


0

tl; dr: ইন সোর্স কোডে array.c, আপনি 1 বা 2 টি আর্গুমেন্ট পাস করেছেন কিনা তার উপর নির্ভর করে বিভিন্ন ফাংশনগুলি ডাকা হয়Array#slice অপ্রত্যাশিত প্রত্যাবর্তনের মানগুলির ফলস্বরূপ আপনি ।

(প্রথমে, আমি এটি উল্লেখ করতে চাই যে আমি সি তে কোড করি না, তবে বছরের পর বছর ধরে রুবি ব্যবহার করে যাচ্ছি So সুতরাং আপনি যদি সি এর সাথে পরিচিত না হন তবে আপনি মূল বিষয়গুলির সাথে নিজেকে পরিচিত করতে কয়েক মিনিট সময় নেন ফাংশন এবং ভেরিয়েবলের রূব সোর্স কোডটি অনুসরণ করা সত্যিই ততটা কঠিন নয়, নীচে প্রদর্শিত হয়েছে This এই উত্তরটি রুবি ভি 2.3 এর উপর ভিত্তি করে তবে কমবেশি একইভাবে v1.9 এ ফিরে আসে))

দৃশ্যপট 1

array.length == 4; array.slice(4) #=> nil

আপনি যদি Array#slice( rb_ary_aref) এর উত্স কোডটি দেখেন তবে আপনি দেখতে পাবেন যে যখন কেবলমাত্র একটি যুক্তি ( লাইন 1277-1289 ) এ rb_ary_entryপাস হয় তখন তাকে সূচক মানটি (যা ইতিবাচক বা নেতিবাচক হতে পারে) পাস করে বলা হয়।

rb_ary_entryতারপরে অ্যারের শুরু থেকে অনুরোধকৃত উপাদানটির অবস্থান গণনা করে (অন্য কথায়, যদি কোনও নেতিবাচক সূচক পাস করা হয় তবে এটি ইতিবাচক সমতুল্য গণনা করে) এবং তারপরে rb_ary_eltঅনুরোধকৃত উপাদানটি পাওয়ার জন্য কল করে।

হিসাবে প্রত্যাশিত, rb_ary_eltআয় nilযখন অ্যারের দৈর্ঘ্য lenহয় এর চেয়ে বড় বা তার কমে সমান সূচক (এখানে বলা offset)।

1189:  if (offset < 0 || len <= offset) {
1190:    return Qnil;
1191:  } 

দৃশ্য # 2

array.length == 4; array.slice(4, 0) #=> []

তবে যখন 2 টি আর্গুমেন্ট পাস করা হয় (অর্থাত্ সূচনা সূচক begএবং স্লাইসের দৈর্ঘ্য len),rb_ary_subseq ডাকা হয়।

ইন rb_ary_subseq, যদি শুরু সূচক begহয় তার চেয়ে অনেক বেশী অ্যারের দৈর্ঘ্য alen, nilফিরিয়ে দেওয়া হয়:

1208:  long alen = RARRAY_LEN(ary);
1209:
1210:  if (beg > alen) return Qnil;

অন্যথায় ফলাফলের স্লাইসের দৈর্ঘ্য lenগণনা করা হয় এবং এটি শূন্য হিসাবে নির্ধারিত হলে একটি খালি অ্যারে ফিরে আসে:

1213:  if (alen < len || alen < beg + len) {
1214:  len = alen - beg;
1215:  }
1216:  klass = rb_obj_class(ary);
1217:  if (len == 0) return ary_new(klass, 0);

সুতরাং যেহেতু 4 এর সূচক সূচকের চেয়ে বেশি নয় array.length, তাই nilযে কেউ প্রত্যাশা করতে পারে তার পরিবর্তে একটি খালি অ্যারে ফিরে আসে ।

প্রশ্নের উত্তর?

যদি এখানে আসল প্রশ্নটি না হয় "কোন কোডটি এর কারণ ঘটায়?", বরং "ম্যাটজ কেন এমনটি করল?", তবে আপনাকে কেবল পরের রুবিকনফে তাকে এক কাপ কফি কিনতে হবে এবং তাকে জিজ্ঞাসা কর.

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