ধাক্কা পরে স্কেলার মান প্রভাবিত হচ্ছে, না ... (রাকু)


12

Scalarপুশ করার পরে কখন এবং কেন কোনও ধাক্কা পাত্রে রাখা মানটি প্রভাবিত হয় তা বুঝতে আমার সমস্যা হয় have আমি দুটি স্টাইলাইজড উদাহরণে আরও জটিল প্রসঙ্গে যে ইস্যুটি ছড়িয়েছি তা বোঝানোর চেষ্টা করব।

* উদাহরণ 1 * প্রথম উদাহরণে, স্কেলারকে a এর অংশ হিসাবে $iএকটি অ্যারেতে ঠেলাঠেলি করা হয় । পুশ করার পরে, স্কেলারের দ্বারা ধারণকৃত মানটি নির্দেশ ব্যবহার করে লুপটির পরবর্তী পুনরাবৃত্তিতে স্পষ্টত আপডেট করা হয় । এই আপডেটগুলির অ্যারের মানটির উপরে প্রভাব রয়েছে : লুপের শেষে, সমান , আর নেই ।@bList$i++@b@b[0;0]32

my @b;
my $i=0;
for 1..3 -> $x {
  $i++;
  say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
  if $x == 2 {
     @b.push(($i,1));
     say 'Pushed $i   : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
  }
}
say "Post for-loop";
say "Array       : ", @b;
say 'Pushed $i   : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;

আউটপুট উদাহরণ 1:

Loose var $i: Scalar|94884317665520 139900170768608
Loose var $i: Scalar|94884317665520 139900170768648
Pushed $i   : Scalar|94884317665520 139900170768648
Loose var $i: Scalar|94884317665520 139900170768688
Post for-loop
Array       : [(3 1)]
Pushed $i   : Scalar|94884317665520 139900170768688

* উদাহরণ 2 * দ্বিতীয় উদাহরণে, স্কেলারটি $iলুপ ভেরিয়েবল। যদিও $iএটি ধাক্কা দেওয়ার পরে আপডেট করা হয়েছে (এখন স্পষ্ট করে না বলে স্পষ্টভাবে), $iঅ্যারের মধ্যে মানটির ধাক্কা পরেও পরিবর্তন @cহয় না ; অর্থাত্ লুপের পরে এটি এখনও রয়েছে 2, নেই 3

my @c;
for 1..3 -> $i {
  say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
  if $i == 2 {
     @c.push(($i,1));
     say 'Pushed $i   : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;
  }
}
say "Post for-loop";
say "Array       : ", @c;
say 'Pushed $i   : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;;

আউটপুট উদাহরণ 2:

Loose var $i: Scalar|94289037186864 139683885277408
Loose var $i: Scalar|94289037186864 139683885277448
Pushed $i   : Scalar|94289037186864 139683885277448
Loose var $i: Scalar|94289037186864 139683885277488
Post for-loop
Array       : [(2 1)]
Pushed $i   : Scalar|94289037186864 139683885277448

প্রশ্ন: কেন $i@bসময়, উদাহরণস্বরূপ 1 ধাক্কা পর আপডেট মধ্যে $iমধ্যে @cউদাহরণস্বরূপ 2 নয়?

সম্পাদনা : @ টিমোটিমোর মন্তব্যের পরে আমি .WHEREউদাহরণগুলির আউটপুটকে অন্তর্ভুক্ত করেছি । এটি (WHICH / যৌক্তিক) স্কেলার-পরিচয়টি $iএকই রকমের দেখায় যা এর স্মৃতি ঠিকানাটি বিভিন্ন লুপ পুনরাবৃত্তির মাধ্যমে পরিবর্তিত হয়। তবে এটি ব্যাখ্যা করে না যে উদাহরণস্বরূপ 2 টি ধাক্কা স্কেলারটি পুরানো ঠিকানার ("448) এর সাথে মিল রেখে একই WHICH- পরিচয়ের সাথে কেন আবদ্ধ থাকে।


2
আমি কেন উত্তরটি একইরকম বলে মনে করি তার উত্তর দিতে পারি; বাস্তবায়নটি দেখুন: github.com/rakudo/rakudo/blob/master/src/core.c/Scalar.pm6#L8 - এটি কেবলমাত্র ব্যবহৃত বর্ণনাকারীর উপর নির্ভর করে, যা একটি সামান্য অবজেক্ট যা নামের মতো জিনিসকে ধারণ করে ভেরিয়েবল, এবং টাইপ সীমাবদ্ধতা। আপনি যদি এর .WHEREপরিবর্তে ব্যবহার করেন তবে .WHICHদেখতে পাচ্ছেন যে স্কেলারটি প্রতিটি সময় লুপের চারপাশে আসলে একটি আলাদা অবজেক্ট। এটি ঘটে কারণ পয়েন্টি ব্লকগুলিকে "ডাকা হয়" এবং প্রতিটি কলটিতে স্বাক্ষর "আবদ্ধ" থাকে।
টিমোটিমো

@ ইরফ লুপ চলাকালীন, উদাহরণ 1 উদাহরণ 2-এর মতো একই প্যাটার্নটি দেখায়: দুজনেরই। ঠিকানা দ্বারা প্রকাশিত ঠিকানা রয়েছে, যা বলছে, আমি সম্মত। তবে নিজেই এটি ব্যাখ্যা করে না যে উদাহরণ 2 উদাহরণের চেয়ে পৃথক শেষের দিকে কেন আসে
ওজির

উত্তর:


5

একটি স্কেলারের মান কেবল একটি ধারক। আপনি এগুলি আদিম মানের পরিবর্তে এক ধরণের স্মার্ট পয়েন্টার হিসাবে ভাবতে পারেন।

আপনি যদি একটি অ্যাসাইনমেন্ট করেন

$foo = "something"; #or
$bar++;

আপনি স্কেলারের মান পরিবর্তন করছেন, ধারকটি একই থাকবে।

বিবেচনা

my @b; 
my $i=0; 
for 1..5 -> $x { 
  $i++; 
  @b.push(($i<>,1)); # decontainerize $i and use the bare value
} 
say @b;

এবং

my @b; 
my $i=0; 
for 1..5 -> $x { 
  $i := $i + 1;  # replaces the container with value / change value
  @b.push(($i,1)); 
} 
say @b;

উভয়ই প্রত্যাশার মতো কাজ করে। তবে: উভয় ক্ষেত্রেই তালিকার জিনিসটি আর পরিবর্তনযোগ্য নয়, কারণ কোনও ধারক নেই।

@b[4;0] = 99; 

সুতরাং মারা যাবে। সুতরাং ঠিক তখন লুপ ভেরিয়েবলটি ব্যবহার করুন?

না।

for 1..5 -> $x { 
  @b.push(($x,1)); # 
} 
@b[4;0] = 99; #dies

এমনকি যদি আমরা পরিবর্তনীয় জিনিসের একটি তালিকা নিয়ে পুনরাবৃত্তি করি।

my $one = 1;
my $two = 2;
my $three = 3;
my $four = 4;
my $five = 5;

for ($one, $two, $three, $four, $five) -> $x { 
  @b.push(($x,1)); 
} 
@b[4;0] = 99; #dies

সুতরাং এখানে কোনও এলিয়াসিং ঘটছে না, পরিবর্তে লুপ ভেরিয়েবল সর্বদা একই ধারক এবং অন্যান্য ধারক থেকে আসা মানগুলি নির্ধারিত হয়।

যদিও আমরা এটি করতে পারি।

for ($one, $two, $three, $four, $five) <-> $x { 
  @b.push(($x,1)); 
} 
@b[4;0] = 99; # works

for ($one, $two, $three, $four, $five) -> $x is rw { 
  @b.push(($x,1)); 
} 
@b[4;0] = 99; # works too

"জিনিসটিকে" পরিবর্তনীয় করার একটি উপায় হল একটি মধ্যবর্তী ভেরিয়েবল ব্যবহার করা।

for 1..5 -> $x { 
  my $j = $x;
  @b.push(($j,1)); # a new container 
} 
@b[4;0] = 99;

ঠিকভাবে কাজ করে. বা মূল প্রসঙ্গে খাটো এবং আরও অনেক কিছু

my @b; 
my $i=0; 
for 1..5 -> $x { 
  $i++; 
  @b.push((my $ = $i, 1)); # a new anonymous container
} 
@b[4;0] = 99;
say @b; # [(1 1) (2 1) (3 1) (4 1) (99 1)]

আরো দেখুন:

https://perl6advent.wordpress.com/2017/12/02/#theoneandonly https://docs.perl6.org/language/containers


1
পরিবর্তে ($x,1), আপনি এটিও করতে পারেন [$x,1]যা একটি নতুন ধারক তৈরি করবে ( 1
বিটিডব্লিউর জন্যও

@ এলিজাবেথমতিজসেন তবে তারপরেই অ্যারে হ'ল "উত্তোলন" হ্যাঁ?
হলি

"উত্তোলন" বলতে কী বোঝায় তা নিশ্চিত নন তবে আপনি যদি সৃষ্টির মানগুলিকে ধারক করে তোলেন তবে হ্যাঁ।
এলিজাবেথ ম্যাটিজসেন

@ হোলি আপনার উত্তরের জন্য ধন্যবাদ। আমি নিশ্চিত না যদিও এটি প্রশ্নের উত্তর দেয় কিনা। আপনার উত্তরটি ধারকটির পরিবর্তনের দিকে দৃষ্টি নিবদ্ধ করে, যা আমি মনে করি আমি বুঝতে পেরেছি। আমি যা বুঝতে পারি না কেন প্রথম উদাহরণে ধাক্কা পাত্রে $ i - বা আরও ভাল: এর মান - ধাক্কা দেওয়ার পরে আপডেট করা হয়, যখন দ্বিতীয় উদাহরণে ধাক্কা ধারকটির মান এই মুহুর্তে স্থিরভাবে মানটির সাথে আবদ্ধ থাকে ধাক্কা। প্রথম উদাহরণটি আমার কাছে কিছুটা অর্থবোধ করে (কনটেইনারটি পয়েন্টারটি Intঅবজেক্ট -> Intলুপের জন্য প্রতিস্থাপিত হয় -> নতুন পয়েন্টারে পয়েন্টার Int) তবে দ্বিতীয়টি তা করে না।
ওজি

@ হোলি আমি প্রশ্নটি পরিষ্কার করার চেষ্টা করব।
ওজি

3

কিছু সময়ের জন্য আমার উপরের প্রশ্নটি নিয়ে খেলা এবং চিন্তা করার পরে, আমি একটি উত্তর চাইব ... এটি আমার পক্ষ থেকে খাঁটি অনুমান, সুতরাং দয়া করে এটি নির্দ্বিধায় যদি এটি হয় তবে নির্দ্বিধায় বলতে পারেন, এবং যদি আপনি জানতে চান, কেন ...

প্রথম উদাহরণে, $iলুপের লিক্সিকাল স্কোপের বাইরে সংজ্ঞায়িত করা হয়। ফলস্বরূপ, $iলুপ এবং এর পুনরাবৃত্তির থেকে পৃথক রয়েছে। $iলুপের অভ্যন্তরীণ থেকে কখন রেফারেন্স করা হয়, কেবল $iতখনই এটি প্রভাবিত হতে পারে। এটি এটিকে $iধাক্কা দেয় @bএবং এর বিষয়বস্তুগুলি পরে লুপে পরিবর্তিত হয়।

দ্বিতীয় উদাহরণে, $iলুপের লেক্সিক স্কোপের ভিতরে সংজ্ঞায়িত করা হয়। @ স্টিমোটিমো যেমন উল্লেখ করেছে, পয়েন্ট ব্লকটি সাব্রোটিনের মতো প্রতিটি পুনরাবৃত্তির জন্য ডেকেছে; $iসুতরাং প্রতিটি পুনরাবৃত্তির জন্য তাজাভাবে ঘোষণা করা হয় এবং এটি সম্পর্কিত ব্লকে স্কোপ করা হয়। $iলুপের অভ্যন্তরে যখন রেফারেন্স হয় তখন রেফারেন্সটি হ'ল ব্লক-পুনরাবৃত্তি-নির্দিষ্ট হয়ে থাকে $i, যা সাধারণত লুপের পুনরাবৃত্তিটি শেষ হয়ে গেলে অস্তিত্ব লাভ করে। তবে কোনও একদিকে $iধাক্কা দেওয়ার কারণে @c, ব্লক-পুনরাবৃত্তি-নির্দিষ্ট $iহোল্ডিংয়ের মানটির 2পুনরাবৃত্তি সমাপ্তির পরে আবর্জনা সংগ্রহকারী দ্বারা মুছে ফেলা যায় না। এটি অস্তিত্ব থাকবে ... তবে $iপরবর্তী পুনরাবৃত্তির থেকে এখনও আলাদা হবে ।


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