Pull to refresh
40
0
Марат @maratk

User

Send message
В обоих примерах Клабник пишет что это всего лишь примеры, поэтому в первом просит не бросаться на Post.all, а во втором — не пытаться решить проблему первым способом (потому что это тоже правильно, но надо показать другое).
Оба варианта не очень, по-моему, вписал третий (почти Ваш).
Вот он, голос моей совести! :)
Опубликовал. Перевод был готов, оставались мелочи по оформлению и вычитке.
ОК, будем продолжать! :)
да, согласен, хотя казалось, что объяснил достаточно хорошо :)
Класс В имеет метод (можно назвать его лучше build), создающий объекты (один или несколько, зависит от других условий и решается по ходу работы программы). Сам объект класса В объекты других классов не инстанциирует, их конструкторы вызываются снаружи.
Класс В уже написан и функционирует, нужно или поменять все вызовы save на save(false) (что в принципе проще), или вывернуться вот таким образом, переопределив поведение метода, если он вызывается изнутри определенного контекста (что ГОРАЗДО сложнее и даже скорее всего неправильно, потому что другие программисты не подозревают о такой подставе, и реально стало интересно с точки зрения возможностей руби).

Таким образом, интерфейс класса В и параметры вызова save менять нельзя :)

Соображу утром более адекватный пример кода — допишу сюда.
если коротко, то сейв в классе В не вызывается прямо, плюс внутри сохраняются несколько объектов (это уже в ответ на следующий вариант —
Copy Source | Copy HTML
  1. class B
  2.   def initialize
  3.     @a=A.new
  4.     @a.instance_eval <<-EOF
  5.       alias :old_save :save
  6.       def save(validate = false)
  7.         old_save(validate)
  8.       end
  9.     EOF
  10.   end


В общем, если никому не интересно — так и скажите, закрою в приват, буду сам любоваться.
судя по минусам в рейтинге статьи
похоже, блог пора переименовывать из Ruby в «Мышевозы» или как-нибудь еще.
Да, у этого парня все такое — для «поковырявшихся» :) Поэтому я и люблю его читать :)
с ретурном оказалось еще хитрее (innig.net/software/ruby/closures-in-ruby.rb):

# I'll spare you the rest of the experiments, and give you the behavior of all 7 cases:
#
# «return» returns from caller:
# 1. block (called with yield)
# 2. block (&b => f(&b) => yield)
# 3. block (&b => b.call)
# 4. Proc.new
# 5. proc in 1.9
#
# «return» only returns from closure:
# 5. proc in 1.8
# 6. lambda
# 7. method

т.е. из блока и Proc return вернет из внешней функции, а из lambda — только из нее (как из настоящей лямбда-функции)
скорее всего, «трудности перевода» ))
Я имел ввиду комментарии после статьи:
Colin Curtin:
Кое-что, о чем нужно помнить про non-local-return: блок должен иметь доступ к контексту, из которого вы хотите вернуться.
и дальше. Т.е. в моем понимании нельзя написать оторванный от контекста Proc или lambda с директивами super, return или yield и надеяться, что он будет работать. Нужен контекст для этих super, return или yield.
Поэтому они и умеют все это делать, поскольку сохраняют контекст, это я понимаю. Я писал комментарий «сверху», а не «снизу». Что именно я не понимаю?
вот и я о том же :)
но есть объективные особенности — например ретурн изнутри лямбда-функции. Это дает конкретные возможности программисту. Если они нужны — пусть берет руби, если нужны другие — пусть берет другой язык.
Религиозная вера заканчивается, когда появляется понимание (или переходит на другой уровень). Я бы сказал что лучше тот язык, который правильнее реализует изначальные ООП концепции, но они тоже не стоят на месте.
Но из-за таких мелочей (как описанные в посте) язык приобретает возможности реализовывать более специфические тонкости, заметные на более низком уровне, но облегчающие создание фреймворков и работу с ними (хотя в других вещах может быть и усложняющие), как опять-таки тот же респонд_ту.
В питоне будут свои тонкости, способные упрощать работу в чем-то, но для характеристики «лучше-хуже» оснований нет (если удобство кодирования, рефакторинга, подключения расширений, документации, настройки сервера, скорость интерпретатора, масштабируемость не отличается в десятки раз), есть только заложенные в сам язык возможности и обусловленные этим более удобно решаемые задачи. Для одной задачи удобнее этот язык, для другой — этот. Т.е., например, руби благодаря своим возможностям, имеет такие преимущества, а питом — такие. Это объективно. «Лучше-хуже» — субъективизм. Если в дискуссию включить программиста микропроцессоров, он скажет, что хуже руби и питона вообще нет, а для веба — наоборот. Есть набор характеристик языка, который отражает эти возможности. Фреймворки (мне кажется) их часто нивелируют, потому что тоже предназначены для решения специфических задач, и особенности языка чаще видны внутри, чем снаружи, а наружу уже вылазят особенности фреймворков, о которых тоже можно бесконечно спорить «лучше-хуже», но по сути если нет выигрыша по критическим параметрам в разы объективно лучшего найти не получится.
Фаулера читать не лень :), в заблуждения вводят названия фреймворков (например, когда-то я думал, что ActiveRecord — это чисто название фреймворка, а не название паттерна изначально).
Пока ехал в метро, понял что session — это и есть UnitOfWork, а заодно и закрались сомнения относительно рубишного ДатаМаппера.
Спасибо за короткий анализ, у Фаулера его нет.
Может знаете, есть ли на руби правильная реализация ДатаМаппера?
спасибо, тонкая деталь
в дополнению к habrahabr.ru/blogs/ruby/86882/#comment_2619504
в частности, это упрощает рефакторинг кода, рендеры и ретурны внутри respond_to, простую реализацию синхронизации мютексов
даже в плюсах есть возможность вызвать приватный метод (насколько я помню) с помощью friend. Может я ошибаюсь по поводу самой возможности, но то, что это идет в разрез с инкапсуляцией — это точно.
да, но в руби DataMapper тоже свой есть, тем не менее и он более удобочитаемый, чем
session.query(User).filter_by(name=u»Маша").first()
:
zoo = Zoo.first(:name => 'Luke')

Information

Rating
Does not participate
Location
Киев, Киевская обл., Украина
Registered
Activity