Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Ruby: Общие вопросы > передача парметров


Автор: wpp 8.4.2006, 15:43
Что-то не пойму, (в документации ничего не нашел) как передаются параметры в методы? По ссылке или по значению? Или оба способа? Ткните, пожалуйста в документацию, где это описано.

Автор: skalex 9.4.2006, 12:10
wpp, см. http://www.rubygarden.org/faq/entry/show/27

Автор: skalex 9.4.2006, 12:29
Вот еще по ссылка по теме: http://www.ruby-forum.com/topic/41160#8084

Автор: Pete 9.4.2006, 21:36
Методы, заканчивающиеся символом "!", изменяют объект. А вообще аргументы передаются по значению.

Автор: Rubynovich 7.6.2006, 20:08
Цитата(Pete @ 9.4.2006,  21:36)
Методы, заканчивающиеся символом "!", изменяют объект. А вообще аргументы передаются по значению.

Всегда по значению, а методы ! лучше не использовать. Поверьте старому еврею...  "некошерные" они! 

Автор: Pete 9.6.2006, 16:32
Цитата(Rubynovich @  7.6.2006,  20:08 Найти цитируемый пост)
...лучше не использовать...

Здорово еще раз!
Твои аргументы? 

Автор: simanyay 9.6.2006, 16:38
Цитата

Всегда по значению, а методы ! лучше не использовать.


Это типа мне ActiveRecord::Base.save! нельзя использовать? smile Или Hash.merge!? Ничего такого в этих методах, просто восклицательный знак обозначает то, что они изменяют состояние вызывающего объекта. А в отношении ActiveRecord::Base.save! означает то, что при ошибке он выкинет исключение, а не просто вернет false.

«не верьте мне, голубчик, я недостаточно пожил на этом свете» http://narisoval.ru.  

Автор: Rubynovich 9.6.2006, 22:27
Цитата(Pete @ 9.6.2006,  16:32)
Цитата(Rubynovich @  7.6.2006,  20:08 Найти цитируемый пост)
...лучше не использовать...

Здорово еще раз!
Твои аргументы?



Шалом, когда идет связка методов типа:
Код

maccuB.find_all!{ |i| i < 5 }.join


То их использование будет только мешать, т.к. значение, которое вернул .join ты не получишь, а исковеркать массив уже исковеркал, причем ненужными данными.

Использовать методы ! можно только тогда, когда нет связки (один метод) и необходимо присваивание. По своему опыту могу сказать, что вероятность такого случая стремиться к 0 (не в RoR). =)  

Автор: Pete 9.6.2006, 22:39
Цитата(Rubynovich @  9.6.2006,  22:27 Найти цитируемый пост)
maccuB.find_all!{ |i| i < 5 }.join

Не, до таких извратов дело не доходило... 

Автор: Rubynovich 9.6.2006, 22:49
Цитата(Pete @ 9.6.2006,  22:39)
Цитата(Rubynovich @  9.6.2006,  22:27 Найти цитируемый пост)
maccuB.find_all!{ |i| i < 5 }.join

Не, до таких извратов дело не доходило...

Дойдет, и еще не до таких... вот кусок моей сегодняшней программы:
Код

Dir['~book/super/*.html'].inject(""){ |res,file_name|
    res + [ [/<br( \/)?>/,"\n"],[/\s+/,' '] ].inject( IO.read( file_name ) ){ |result, array|
        result.gsub( *array )
    } + "\n\n"
}.display( File.open('~book/result.html','w+') )
  

Автор: Vanoha 30.6.2006, 09:33
Параметры в методы передаются не по значению, а как ОБЪЕКТЫ!!!

Иллюстрирующий пример:
Цитата
def inc(var)
  var.succ!
end
s='aaa'  # => 'aaa'
inc(a)   # => 'aab'
a  # => 'aab'

В большинстве случаев это выглядит, как передача значения из-за следующего:
в Ruby любая операция над объектом (кроме специальных "деструктивных" методов с '!') приводит не к модификации объекта, а к созданию новой копии этого объекта  (не нового экземпляра этого класса, а именно новой копии объекта).
Поэтому, если мы делаем что-то внутри метода над объектом, то получаем новый объект, а старый не модифицируем. При этом переменная из контектста вызова остается неизменной, т.к. она "именует" "старый" объект.

Исключением являются Fixnum, Float, nil/false/true в силу специфики хранения и обработки (Float и Fixnum хранятся и обрабатывается вместе с "именем", а nil/false/true - вообще не имеют "экземпляров" как таковых).

Именно поэтому в большинстве случаев все выглядит так, как если бы в метод передавалось значение (если не используются специальные методы изменяющие сам объект [с '!']).

ID объекта в Ruby уникальны независимо от контекста, поэтому можете придумать свою проверку с использованием object_id, например:
Цитата
def test(val)
  val
end

s='djhsajdh'
s.object_id==test(s).object_id  # => true

Передача параметров в виде объекта дает следующие преимущества/функциональность:
1. нет копирования данных при вызове, что при сложных структурах дает выигрыш по скорости.
2. проще работать с уникальными методами объектов
3. просто работают методы, возвращающие/устанавливающие значения переменных объекта (ala "@var). 

Еще один пример, иллюстрирующий "подводные камни".
Цитата
def test(n)
  n[3]='qw'
end

a=[1,2,3,4]  # => [1,2,3,4]
test(a)  # => 'qw'
a   # => [1,2,3,'qw']

 

Автор: V.A.KeRneL 4.12.2006, 06:04
Цитата(Vanoha @ 30.6.2006,  09:33)
Параметры в методы передаются не по значению, а как ОБЪЕКТЫ!!!

Правильно! Спасибо, Vanoha. Хоть один внимательный участник нашёлся. Значит не пропадём! smile 
Фактические аргументы передаются в метод (и замещают тем самым формальные параметры) как объекты, т.е. ПО ССЫЛКЕ, а не по значению!

Автор: Pete 4.12.2006, 13:16
Цитата(V_A_KeRneL @  4.12.2006,  07:04 Найти цитируемый пост)
Фактические аргументы передаются в метод (и замещают тем самым формальные параметры) как объекты, т.е. ПО ССЫЛКЕ, а не по значению!


Все правы. Просто одни имели в виду базовые классы для работы с числами (Numeric), а другие -- сложные объекты (строки, массивы и т.п.). В этом плане ruby не отличается от С.

Автор: V.A.KeRneL 9.12.2006, 23:23
Цитата(Pete @  9.6.2006, 22:39 Найти цитируемый пост)

Цитата(Rubynovich @  9.6.2006,  22:27 Найти цитируемый пост)
maccuB.find_all!{ |i| i < 5 }.join

Не, до таких извратов дело не доходило...


А зря!.. Извращаться полезно! Не слушать доводы о том, что так делать низя, а надо всегда вот эдак, недвусмысленно советовал сам Бьерн Страуструп в книжке «Язык программирования C++». Хотя бы потому, что лучше запомнишь, если на собственной шкуре это испытаешь. Вот ты (Можно я на «ты», Петь? smile) не достаточно извращался, т.е. экспериментировал с Ruby и теперь не заметил, что Rubynovich привёл в качестве примера метод, которого нет ни в ядре, ни в стандартной библиотеке Рубина.
find_all есть в модуле Enumerable: http://www.ruby-doc.org/core/classes/Enumerable.src/M003160.html
А find_all! нету: http://www.ruby-doc.org/core/

Автор: Pete 10.12.2006, 20:27
Цитата(V_A_KeRneL @  10.12.2006,  00:23 Найти цитируемый пост)
Можно я на «ты», Петь?

 smile 
Цитата(V_A_KeRneL @  10.12.2006,  00:23 Найти цитируемый пост)
Не слушать доводы о том, что так делать низя

Даже если речь идет о goto (кстати, со слов того же Страуструпа)?! Не, спасибо, я уже это проходил.  smile 
Цитата(V_A_KeRneL @  10.12.2006,  00:23 Найти цитируемый пост)
не достаточно извращался

Мне сейчас гораздо важнее и интереснее освоить разные алгоритмы, а не особенности языка (си не в счет)... Жаль, р-форум не пашет, http://www.msiu.ru/~roganov/2sem/misc002/ есть ссылки на некоторые диалоги. Помнится, кто-то из нашего общего с тобой начальства ( smile ) говорил много интересного по данному поводу. В частности, то, что главное в решении задачи не безупречное знание синтаксиса языка, а умение работать с алгоритмами и математикой применительно к своей проблеме.

Хотя, конечно, в перспескиве......
 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)