LINUX.ORG.RU

Полнота парадигм в Ruby

 , , , ,


1

3

Доброго времени суток ананимусы и аналитики ЛОР'а! В связи с последним г*ом, которое заявил Гвидо решил окончательно сползать с Python 3.x на что-то более вменяемое. Полностью переходить на tcl пока не хочу (много слишком веществ надо потреблять), хочется немного батареек побольше. Ранее использовал Ruby в разрезе ООП. Заинтересовало вот что:

1. Как обстоят дела на Ruby с ФП? Насколько он поддерживает данную парадигму? Хотя бы на уровне Scheme или Clojure оно или на том же уровне, что и Python?

2. Как обстоят дела с меттапрограммированием? Можно ли писать такие же классные вещи как на tcl или lisp-family (макросы, программирование синтаксиса, etc.)? Насколько хорошо с этим в рубине?



Последнее исправление: iMushroom (всего исправлений: 1)
Ответ на: комментарий от special-k

Нет, он о плюсовых operator=, видимо. Чтоб вот можно было писать t = something, и это давало какое-то неожиданное поведение. ТС не знает сам, чего хочет.

cdshines ★★★★★
()
Ответ на: комментарий от iMushroom

Скажем в выражении a=2, «=» - это оператор присваивания.
теперь точно вкурил

Не вкурил ты. Если а - инстанс класса, = отработает только так, как положено, т. е. содержимое объекта справа станет и содержимым объекта слева. А special-k привел пример того, что можно - сеттеры переменных инстанса, когда ты внутрях у а какие-то переменные, опять же, стандартным поведением = изменяешь. Ты должен сам себе понять, что переопределение = в стиле

И все - же, можно ему задать что-то иное, нежели привязываение значения к переменной?

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

def a=(arg)
  puts "#{a}, #{arg}"
end
но это уже совсем лютый пи$#ец.

cdshines ★★★★★
()
Последнее исправление: cdshines (всего исправлений: 1)
Ответ на: комментарий от cdshines

содержимое объекта справа станет и содержимым объекта слева

Это неверно в общем случае, в силу ссылочной природы связывания.

но это уже совсем лютый пи$#ец.

Почему? Переопределить =, как сначала написать в лог, что произошло, а потом уже присвоить, например.

aedeph_ ★★
()
Ответ на: комментарий от aedeph_

Почему же? Слева объект, и справа объект.

irb(main):001:0> s1 = 's1'
=> "s1"
irb(main):002:0> s2 = s1
=> "s1"
irb(main):005:0> s1.hash==s2.hash
=> true
Выполню, например, s2.clear, в s1 тоже ничего не останется. Как это расходится с утверждением «содержимое объекта справа станет и содержимым объекта слева»?

Почему? Переопределить =, как сначала написать в лог, что произошло, а потом уже присвоить, например.

Полезно, но никак не согласуется с идеей «один метод - одно действие». Я бы уж тогда вынес в отдельный метод и дергал, но это уже дело архитектуры. И, в любом случае, = будет, так или иначе, выполнять то, что должно, т. е. не «что-то иное, нежели».

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

iMushroom

хочу обратить внимание

сеттеры переменных инстанса

Это, как бы, не так.. в руби нет понятия сеттера в принципе - есть имитация (частный случай вызова метода). Но смотрите, выглядит так, словно a - это локальная переменная, для которой переопределен оператор = (единственное отличие - необходимость использования self при присвоении). Методы a и a= даже нельзя вызвать снаружи объекта. И это не какие-то космические костыли, это элементарнейшая конструкция языка, это гибкость.

class A
  def inc_a!
    self.a += 1
    a
  end

  protected
  def a= v
    @a = v * 2
  end
  def a
    @a ||= 0
  end
end

t = A.new
p t.inc_a! #2
p t.inc_a! #6
t.a #NoMethodError
t.a = 1 #NoMethodError
special-k ★★★★
()
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

1) А что такое сеттер, если не метод, который устанавливает переменную объекта? Если уж на то пошло, то в тривиальных случаях проще писать attr_writer :a, не так ли?

2) В том-то и суть, что a= - это просто метод, а не перегрузка = для типа переменной а. ТС же как раз спрашивал про перегрузку = вообще, чего нельзя сделать.

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

Или, если уж на то пошло, то совсем так:

irb(main):001:0> class C
irb(main):002:1> attr_accessor :a
irb(main):003:1> end
=> nil
irb(main):004:0> b = C.new
=> #<C:0x00000002311210>
irb(main):005:0> b.a = 1
=> 1
irb(main):006:0> b
=> #<C:0x00000002311210 @a=1>
irb(main):007:0> b.instance_variable_set("@a", 2)
=> 2
irb(main):008:0> b
=> #<C:0x00000002311210 @a=2>
Это же все одно, что а=, что attr_writer, что instance_variable_set. Последний-то случай вы за сеттер признаете?

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

А что такое сеттер

Просто когда говорят сеттер, то у меня в голове возникает какая-то специфичная конструкция, тесно связанная с понятием «свойство», а в руби нет свойств, следовательно нет и сеттеров. А указанное выше - абсолютно типичный вызов метода.

a= - это просто метод, а не перегрузка = для типа переменной а.

Кто спорит, но ведь выглядит именно так. Так какая разница.

special-k ★★★★
()
Ответ на: комментарий от special-k

Ага, какая разница. Сегодня ты показал тсу, что можно сделать что-то подобное перегрузке, а завтра он попробует сделать это для класса в целом, не сможет, и будет на лоре обсирать уже не питон, а руби. Нет пути!

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

Последний-то случай вы за сеттер признаете?

мм.. не знаю.. это важно?) Это больше метапрограммирование чем сеттер)

для меня эталонный сеттер вот:

  public class ScheduleTask
  {
    private int hours;
    public int Hours
    {
      set
      {
         if ( (value >= 0) && (value < 24) )
         {
           hours = value;
         }
      }
    }
  }

ИМХО бесполезная штука, аналог, по функционалу, которой в руби будет выглядеть и лаконичнее, и красивее, и логичнее, и органичнее.

special-k ★★★★
()
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

Во-первых, в самом общем смысле: In computer science, a mutator method is a method used to control changes to a variable. И только In programming languages that support them, properties offer a convenient alternative without giving up the utility of encapsulation.

http://en.wikipedia.org/wiki/Accessor. Особенно #Ruby_example часть:)

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

ах.. руби часть.. такая нормальная) Да, я говорю о собственных ассоциациях, на основе собственного опыта работы с языками. Просто я не работал с языками без пропертей кроме руби..

special-k ★★★★
()
Последнее исправление: special-k (всего исправлений: 1)
Ответ на: комментарий от special-k

Кстати, bang'и использовать, если нету метода без него, не по феншую. Правильно было бы назвать inc_a.

drakmail ★★★★
()
Ответ на: комментарий от special-k

Спасибо за пояснения, рассматриваю возможность того, что понаписал полностью на рубин. У вас есть опыт написания больших приложений на руби? (не рельсы)

iMushroom
() автор топика
Ответ на: комментарий от iMushroom

Сейчас пишу проект, в котором уже 6.5к строк на руби

Files:         130
Modules:        60
Classes:       109
Constants:     173
Methods:       554
(статистика от yard)

Пока все идет нормально.

special-k ★★★★
()
Ответ на: комментарий от cdshines

«содержимое объекта справа станет и содержимым объекта слева»

Я имел ввиду, что фактически сначала будет сделан эвал выражения справа. Если это назвать содержимым - то я согласен.

это уже дело архитектуры.

Разумеется. Для этого берут жабу или сишарп и решают такую важную с точки зрения архитектуры подзадачу глобально и надёжно.

aedeph_ ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.