روبی و pass by value

آیا با این مثال سطحی میشه اثبات کرد که روبی pass by value و یا این که مفهوم pass by value یا refrence مفهوم عمیق تر.

a = 10 b = a puts b a = 20 puts b
خروجی b در هر دوحالت «۱۰»
آیا اگه روبی pass by refrence بود خروجی b در حالت دوم تغییر می کرد؟

نه فرقی نداشت چون در زبان هایی که این قابلیت وجود داره اصولا با pointer ها که به reference اون حافطه ارتباط داره این کار انجام میشه برای Go این مثال ببینید

https://gobyexample.com/pointers

1 پسندیده

@watermelon اين مثال رو چطورى تعريف ميكنيد؟ خيلى سادست به خودتون ميسپارم

شايد مطلب زير به كار بياد

آیا طبق این صفحه و مثالی که زده ( share کردن یک سایت ) ، نباید در زبان هایی که pass by refrence هستند ، و در مثالی که من زدم متغیر b در حالت دوم تغییر کنه؟ در واقع اگر طبق مثال نگاه کنیم ،‌ باید همه تغییرات نسخه اصلی (که در اینجا متغیر a ) هست ، در b قابل مشاهده باشه ، که این طور نیست. چه طور استدلال میشه؟ مثالی که stack over flow زده خیلی دقیق نیست ، یا این که من بد فهمیدم.

من فرق بین مثال شما و مثال خودم رو نمی فهمم‌ !! چرا در مثال شما متغیر ها نسبت به تغییرات هم واکنش نشان می دهند ولی در مثال من متغیر b با تغییر a ، عوض نمیشه ؟! آیا این فقط به خاطر نوع آرایه بودن متغیر هاست؟

1 پسندیده

نكته همين بود:
با استفاده از = در واقع یک variable به يك object ارجاع داده میشه, پس وقتى كه داريم a = b يعنى a و b به ابجكت مشابه ارجاع دارند.
اما وقتی b یا a با استفاده از assignment operator یا همون = به object جدید اجاع داده میشوند, مثل a = 1 یا b = 100, دیگه به object یکسانی مرتبط نیستند.
حالا با تغییر یک ایتم از ارایه ای که در مثال نشون دادم عمل assignment برای b به object جدید اتفاق نیفتاده پس همچنان a و b به object یکسانی ارجاع دارند.
یک راه حل مناسب: (Shallow Copy)
http://ruby-doc.org/core-2.4.0/Object.html#method-i-dup

اگر کافی نبود همینجا بپرسید

1 پسندیده

نکته مهم اینه کهpass by value در اکثر زبان‌ها عملکرد معمولی‌ به حساب میاد در مثال شما اگر روبی pass by reference بیشتر پشتیبانی‌ میکرد فرقی‌ نداشت چون وقتی‌ b به a assign می‌شه یهobject جدید درست می‌شه. a, b هیچ حافظه با هم استفاده نمی کنند و کاملا مجزا هستند
برای اینکه هر دو به یک آدرس حافظه اشاره کنند باید از pointer استفاده کرد.
مثال شما در Go


مثال در Go ولی با reference

b := &a
b را به آدرس حافظه a ارتباط میده و
‍‍‍b*
هرچی که در آدرس ذخیره شده را نشون میده

1 پسندیده

با توضیحاتی که شما دادید ، قسمت زیادی از گنگی مبحث برام حل شد ولی هنوز این قسمت از حرف شما رو درست نفهمیدم . اگر این جوری که شما می گید باشه پس چرا؟

a = toomaj b = a print b a[0] = samdvr print b

خروجی => toomaj
samdvrtoomaj

روبی تا جائی‌ که ممکن می‌خواد در یه اسکوپ object اضافه درست نکنه تا وقتی‌ که لازمه.این برای حفظ حافظه هست ولی‌ این به این معنا نیست که آبجکت‌ها با رفرنس هستن. به مثال زیر نگاه کنید

irb(main):001:0> a=1
=> 1
irb(main):002:0> b=a
=> 1
irb(main):003:0> a.object_id
=> 3
irb(main):004:0> b.object_id
=> 3
irb(main):005:0> a= 5
=> 5
irb(main):006:0> a.object_id
=> 11
irb(main):007:0> b.object_id
=> 3

https://launchschool.com/blog/references-and-mutability-in-ruby
هم تکمیل تر توضیح داده

1 پسندیده

همونطور كه عرض كردم Assignment ارجاع رو update ميكنه، در مثال شما a = 5 يعنى ارجاع به ابجكت جديد. به همين دليل object_id عوض ميشه.

2 پسندیده

با این شرایط آیا امکان داره a رو به طوری تغییر بدیم که object_id عوض نشه. یعنی مثلا به طوری a رو برابر ۵ کنیم که b هم نسبت به اون تغییر پیدا کنه.

بايد بگم كه = در روبى علامت تساوى نيست، و a = 5 معنيش اين نيست كه ما a را بربر 5 كرديم بلكه a رو به 5 در واقع assign كرديم يا ارجاع داديم.
روبى وظيفه memory allocation رو براى ما به عهده گرفته و با استفاده از GC حافظه هايى كه از scope خارج ميشند رو در بكگراند آزاد ميكنه در عين حال هدف روبى اينه كه برنامه نويس رو از پوينتر ها و رفرنس ها دور نگه داره.
راه هايى براى تغيير اين رفتار گفته شده اند كه چندان منطقى نيستند.