LINUX.ORG.RU

Релиз Ruby 2.1

 


5

9

Прекрасный новогодний подарок преподнес Matz всем любителям и профессионалам программирования на языке Ruby — релиз Ruby 2.1. В целом новый выпуск языка и среды исполнения написанного на нем кода продолжает эволюционное развитие Ruby и практически не вносит кардинальных или ломающих изменений. Кроме того, что стандартный интерпретатор стал работать быстрее, заявлены следующие отличительные особенности Ruby 2.1:

  • Кэширование названий методов. Теперь когда интерпретатор встречает название какого-то метода объекта, он производит поиск этого метода, после чего сохраняет указатель на него в байткоде. Если у вас есть код, в котором для объектов одного и того же типа часто вызывается один и тот же метод, работа этого участка программы будет ускорена. Для проверки корректности сохраненного значения в кэше MRI использует внутренние счетчики потенциально опасных в плане инвалидации кэшированного метода действий.
  • Поддержка профайлинга кода на уровне MRI. Вы можете измерять производительность вашего кода и отслеживать работу сборщика мусора (благодаря подписке на события запуска/останова сборщика мусора и создания/удаления объектов).
  • Обновленный сборщик мусора RGenGC (с поколениями). Более подробно с ним можно ознакомиться в захватывающей презентации [pdf] с RubyConf.
  • Добавлены суффиксы i и r для записи комплексных чисел.
  • Определение функции (def) теперь возвращает символ ее названия вместо nil.
  • Работа над неоднозначностью объявления refinements, то есть расширения модуля или класса в пределах одного локального файла. Подробнее [pdf].
  • Наконец-то Array#to_h — создание хэша из массива.
  • Сокращение записи «замороженных» строк (str = «mystring"f).
  • Для ускорения операций над очень большими числами используется GMP (The GNU Multiple Precision Arithmetic Library).
  • Обновлены стандартные библиотеки BigDecimal, JSON, NKF, Rake, RubyGems и RDoc.
  • Удалена поддержка из коробки curses (гем curses теперь при необходимости надо установить отдельно).
  • А также многое другое! Подробный список изменений прилагается.

Релиз явно удался на славу и его обязательно стоит попробовать. Исходные коды уже доступны на официальном сайте проекта.

>>> Подробности

★★★★★

Проверено: Shaman007 ()
Последнее исправление: ymn (всего исправлений: 1)

Примечательно также то, что проблемы со скоупами были почти во всех ныне популярных динамических языках. И в Perl, и в Ruby. Но эти проблемы были изящно (с обратной совместимостью) решены и только один гвидо, как обычно, ничего не смог сделать.

deadlock
()
Ответ на: комментарий от anonymous

Либо ты начинаешь доказательно говорить по делу, либо идёшь нахуй, сраный пидор.

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

Ты не программируешь на руби. Значит ты понятия не имеешь от тех траблах которые всплывают при разработке на руби. Так что ты балабол и пидарас.

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

Если я не пишу на Ruby, это не означает, что я никогда не писал и не читал промышленный код на нём, еблан.

deadlock
()
Ответ на: комментарий от anonymous

В отличие о тебя, сосунка, я знаю и Ruby, и Python, и Perl; следовательно, имею возможность сравнивать более или менее адекватно.

deadlock
()
Ответ на: комментарий от tailgunner

Если я пидарасов называю пидарасами, я неадекватен? Ты мне что, предлагаешь лицемерить и сюсюкаться с ними? Да ну нахер. К тому же, какая разница как я общаюсь? Главное по делу.

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

Если я пидарасов называю пидарасами, я неадекватен?

Ну, если учесть, что это выдуманные тобой пидарасы - да.

Ты мне что, предлагаешь лицемерить и сюсюкаться с ними?

Нет, что ты.

К тому же, какая разница как я общаюсь?

Ну, манера общения вообще многое говорит о человеке. И да, тебе самому есть разница, как ты общаешься - ты же не зря плюешься говном с одноразового аккаунта.

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

Чувак, это не бред. Это такое соглашение, «явное лучше скрытого». И оно тоже неплохо работает. Как, например, различать метод класса от обычного метода или статического метода? Или как подсунуть классу обычную функцию под видом метода (если что, метод это не совсем обычная функция с точки зрения рефлексии).

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

Чувак!

Как, например, различать метод класса от обычного метода или статического метода?

Что такое «обычный» метод? А как во всех других языках различают?

deadlock
()
Ответ на: комментарий от Anatolik

Но эта приписочка, почему, черт возьми, она никак не отражена в сигнатуре?

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

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

И да, тебе самому есть разница, как ты общаешься - ты же не зря плюешься говном с одноразового аккаунта.

Да лучше уж поливать говном вас, говноедов, чем цельные сутки кудахтать про дизайн split-а и join-а. А когда речь заходит про действительные проблемы бейсика, такие как lexical scoping, так сразу «пффф, бозе, бозе». Вот это настоящее лицемерие, я считаю.

deadlock
()

К вопросу о замыканиях и счетчиках. Я в питоне не силен, но вроде можно так сделать:

def counter(init_value):
    def count():
        count.func_dict['value'] += 1
        return count.func_dict['value']
    count.func_dict['value'] = init_value
    return count

>>> c1 = counter(0)
>>> c1()
1
>>> c1()
2
>>>
>>> c2 = counter(0)
>>> c2()
1
anonymous
()
Ответ на: комментарий от Anatolik

В Ruby Array — это массив элементов, которые могут быть преобразованы в строку. Соответственно, еще до рантайма, для любого массива #join без аргументов и с корректным аргументом гарантирует, что возвращена будет строка.

Оказывается, ты совсем не знаешь Ruby. Давай учиться:

1. Array() это просто массив объектов, всё. Он ничего не гарантирует относительно своего контента. Уже писал в предыдущем посте почему. Rb и Py в этом плане не отличаются друг от друга.

2. Возможность превращения объекта в строку обещает наличие дефолтного метода to_s. Тоже самое есть и в питоне, метод __str__(). Т.е. это не гарантия Array(), а обещание стандартной объектной модели.

3. Различие естсь только в самом join(). В Rb это получение строки из объекта через duck typing, а в Py строгая типизация (т.е. будет склеивать только объекты-строки без самодеятельности).

Перед продолжением кину пруф на венилятор:

class Foo
    undef_method :to_s
end

[ 1, Foo.new() ].join('-')
Как и положено, Array() ничего не проверил и join() вывалил рантайм ошибку
`join': undefined method `to_s' for #<Foo:0x000000014b2ac0> (NoMethodError)

... Здесь Ruby заблаговременно избавляет вас от того, чтобы вызвать метод для типа данных, который его не поддерживает. Поэтому в Ruby сперва нужно конвертировать в Array

На самом деле оказалось так

В Ruby заблаговременно нужно конвертировать контейнер в Array() потому, что какой-то недалёкий удак прилепил к нему join(), а не сделал его свободной ф-ией или методом строки

Никаких профитов от этого нет, совсем никаких.

С моей точки зрения, это один из главных недостатков питона.

Это было не про Py, а про логическую модель и возможности гетерогенного контейнера вообще.

Конечно, я понимаю, что там есть эта приписочка — «A TypeError will be raised if there are any non-string values in iterable, including bytes objects.». Но эта приписочка, почему, черт возьми, она никак не отражена в сигнатуре?

Потому что сигнатура указывает какие аргументы принимает ф-я и что возвращает назад. Сказано, что принимает iterable и возвращает строку, так оно всегда и есть. Исключение это не аргумент и не возвращаемое значение. Следовательно что? Верно, в сигнатуре негде об этом сказать.

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

Как уже тут было сказано, достаточно определить __iter__ и join заработает, достаточно определить __str__ и объект нормально обработается находясь в коллекции

Не ври, такого сказано не было. Ну а если таки кто-то сказал, то можешь смело плюнуть ему в лицо, ибо это не соответствует действительности.

mashina ★★★★★
()
Ответ на: 99% правильно или 99% удобно от funny_falcon

Вызывать стандартный метод #to_s для элементов клин - это «логично» и «удобно», т.к. это именно то, что пользователю все равно пришлось бы сделать.

Это «логично» для каких-нибудь пыхеров. Для всех остальных это негативный сайд эффект от неявного преобразования. Т.к. __str__() есть по умолчанию у всех объектов (и to_s), то в случае неявного преобразования в join() нет искоробочной возможности проверить корректность работы. В питоне можно легко из коробки получить оба варианта.

Если хотим корректный результат, то

''.join(iterable)
если хотим строку в любом случае, то делаем это явно
''.join(map(str, iterable))
В противном случае нужно писать отдельный валидатор на тип str.

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

сорри, пишу с телефона и пьяныйотвлекаясь, так что скорость ответа не ахти

class Foo():
    # "обычный" метод
    def bar(self): pass

    # статический метод
    @staticmethod
    def  bar(): pass

    # метод класса; "cls" это ссылка на класс, а не на инстанс класса, как "self"
    @classmethod
    def bar(cls): pass
Благодаря красноречивым декораторам, и так всё понятно. Другое дело,что декораторы появились не сразу, и тот же код выглядел так:
class Foo():

    def bar(self): pass

    def  bar(): pass
    ...
    bar = staticmethod(bar)

    def bar(cls): pass
    ....
    bar = classmethod(bar)
Многоточия означают много строк кода. Теперь представим, что нет «глупых» селфов и иже с ними. И что? Как это отличать?

И в других языках другая семантика, и зачастую совсем другая объектная модель. Извините, ваши кони не пляшут.

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

хотя это не замыкание получается. есть словарь похожий на func_dict «func_closure», но он readonly

Замыкание делается как-то так

def count():
    val = [0,]

    def _next():
        val[0] += 1

        return val[0]

    return _next

a = count()
b = count()

print a(), a(), b(), b(),  a(), b()

>>> 1 2 1 2 3 3

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

хотя это не замыкание получается

Это замыкание. counter - локальная переменная.

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

Да, анон, конечно можно и так. Твоё решение практически эквавалентно вот этому: Релиз Ruby 2.1 (комментарий). Но оно не засчитывается, потому как тут ничего не замыкается и следствием этого есть возможность руками изменить счётчик. Правильное решение без nonlocal, например, такое:

def counter():
    c = [0]
    def f():
        c[0] += 1
        return c[0]
    return f
Всё дело в том, что бейсик не разделяет понятий присваивания и связывания, как и положено для говноедов, этим вещи у них - один хуй. Ты спросишь, анон, почему гвидосектанты не объяснили такое поведение и не смогли таки написать counter? А я тебе отвечу, что они даже свой гвидобейсик нихуя не знают, такова их суть.

deadlock
()
Ответ на: комментарий от mashina

Да, всё верно, таким костылём и делается. Не увидел поста.

deadlock
()
Ответ на: комментарий от Virtuos86

Как, например, различать метод класса от обычного метода

Как? О_О Я даже сходу не назову язык в котором есть такая проблема, это чисто питоновая проблема.

явное лучше скрытого

А как быть с инкапсуляцией, например.. Это философское понятие, нужно думать, что делать явным, что нет; удобные программные интерфейсы создавать не просто, и никакой питон здесь не поможет, откровенно говоря он скорее навредит своей косолапостью.

Ох.. вы такие фантазеры.. «я использую питон и потому мои программы понятные»)) Да хренасдва. Говно ваши программы. Говно ваш питон.

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

можешь смело плюнуть ему в лицо

Релиз Ruby 2.1 (комментарий)
http://stackoverflow.com/questions/497765/python-string-joinlist-on-object-ar...

И эта угарная фишка.. чтобы вызвать obj.__str__(), нужно выполнить str(obj) Что религия не позволяет делать прямые обращения к методам?)) Эх.. питонщеги такие питонщеги.

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

Как, например, различать метод класса от обычного метода

Как? О_О Я даже сходу не назову язык в котором есть такая проблема, это чисто питоновая проблема.

Дооо. Для тех, у кого особенно толстая лобовая броня, повторю: в др. языках другой синтаксис и другая объектная модель и такой проблемы естестенным образом возникнуть не может. В ваших рубях есть методы класса и статические методы, и, если есть, как они отличаются в записи?

Говно

Говно

пойди похмелись, откровенный батхерт

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

Релиз Ruby 2.1 (комментарий)

в отличие от тебя, mashina читает внимательно:

Релиз Ruby 2.1 (комментарий)

И эта угарная фишка.. чтобы вызвать obj.__str__() , нужно выполнить str(obj) Что религия не позволяет делать прямые обращения к методам?)) Эх.. питонщеги такие питонщеги.

Питон мультипарадигменный язык. И удобные фичи в нем не обязательно обладают ярковыраженным объектным характером. Я тебе уже писал, что ты лезешь в один язык с привычками, выработанными в другом. Вот идиоматичный код:

map(str, [1, 2, 3])
В хрестоматийную функцию высшего порядка передается массив объектов и функция, возвращается массив строковых представлений этих объектов. (В руби, кстати, так не сделаешь, там «str» будет вызовом функции из-за особенностей семантики языка и синтаксиса. Но я не ору, что руби поэтому днище гребаное — а ведь такой синтаксис обычен для фп-языков, например, — я догадываюсь, что там такие задачи решаются по-другому.)

Вот для таких вещей в питоне и есть len, str, repr, int и так далее — потому что это удобно и этим удобно пользоваться, а не дрочить на пуре ооп стайл.

А __str__ и иже с ним это детали реализации, и за код, в котором их часто дергают без особой необходимости, нужно бить сами знаете чем. Единственное исключение — __init__. Но это из разряда «безобразно, зато единообразно», приходится терпеть.

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

в др. языках другой синтаксис и другая объектная модель

О том и речь, что беспонотовая модель в этом вашем питоне, и синтаксис. Элементарные цепочки преобразования данных выглядят как лютое говно.

как они отличаются в записи?

class A
  def self.a
    puts 'A'
  end
  def a
    puts 'a'
  end
  A.a
  A.new.a
end
var A = function(){}
A.a = function(){console.log('A')}
A.prototype.a = function(){console.log('a')}
A.a()
(new A).a()

То, что творится в питоне, это, млять, нонсенс для ООП. ООП модель питона безмерно корява.

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

ты лезешь в один язык с привычками, выработанными в другом

Нет, скорее мое личное видение ООП совпало с рубиновым. Руби может все, что может питон, даже реализации декораторов есть.

Понимаешь, если ты скажешь, что на питоне можно писать, я не буду спорить. Но если ты будешь говорить, что питон столь же удобен как руби - это не правда.

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

Релиз Ruby 2.1 (комментарий)

Твоё утверждение из предыдущего поста

Как уже тут было сказано, достаточно определить __iter__ и join заработает, достаточно определить __str__ и объект нормально обработается находясь в коллекции, это называется «крякает как утка,

Т.е. ты наврал, хотя этот момент в этом треде много раз объясняли. А теперь скажи зачем это делаешь? Понимаю, прирос психологически к инструменту, всю критику воспринимаешь как свою личную и из-за этого с особым остервенением задаёшь идотские вопросы и искажаешь факты. Нельзя же, наверное, делать это прямо в каждом сообщении, да?

чтобы вызвать obj.__str__(), нужно выполнить str(obj) Что религия не позволяет делать прямые обращения к методам?

Хватает ли тебе образования посчитать кол-во символов в строках «obj.__str__()» и «str(obj)»? Если хватит, то можешь на досуге рассмотреть вариант с map() в аналогичном срезе.

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

Понимаешь, если ты скажешь, что на питоне можно писать, я не буду спорить. Но если ты будешь говорить, что питон столь же удобен как руби - это не правда.

Конечно, это не правда. До Ruby нужно очень долго опускаться вниз засовывая join() в странные места, используя манки патчинг на каждом шагу и придумывая многие другие «гениальные» дизайнерские решения.

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

Хватает ли тебе образования посчитать кол-во символов в строках

внезапно obj.str()

Нет, я понимаю, что тут какая-то заморочка из функциональщины, функции высшего порядка и т.д., но бред это все, так не пишет никто.

Твоё утверждение
достаточно определить __iter__
'a'.join(Foo())
достаточно определить __str__
', '.join(str(x) for x in list)

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

Преимущество записи str(obj) в том, что можно написать map(str, objects). А потом это можно переписать на parallel_map(str, objects). А потом можно переписать на parallel_networked_map(str, objects). А ООП-задрот в это время будет писать врапперы над врапперами.

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

Как я и предполагал, синтаксис отличается. А ты говоришь, проблем таких нигде нет.

Напротив, очень симпатичная модель, логичная и продуманная. Ты просто не умеешь ее готовить :-).

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

ООП модель безмерно корява

Починил. Я ещё не видел ни одного языка, в котором ООП решал бы больше проблем, чем создавал.

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

Декораторы это минимальный сахарок для банальнейшей идеи. В любом языке, где есть функции как объекты первого класса, автоматически есть и возможность пользоваться этим паттерном.

В питоне сравнительно мало синтаксиса, поэтому приходится выкручиваться соглашениями. Если ими проникнуться, всё очень удобно.

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

Я ещё не видел ни одного языка, в котором ООП решал бы больше проблем, чем создавал.

Как я и говорил Релиз Ruby 2.1 (комментарий)

Ну и ладно, с этим спорить я не буду.

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

внезапно obj.str()

Что внезапно? Опять эмоции полезли впереди разума? Ничего не понятно.

Нет, я понимаю, что тут какая-то заморочка из функциональщины, функции высшего порядка и т.д.,

Нет тут никакой заморочки с функциональщиной. Два простых паттерна из простого ООП - итераторы и интерфейс.

но бред это все, так не пишет никто.

Опять врёшь. Как после таких слов можешь рассуждать об ООП?

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

Нет, я понимаю, что тут какая-то заморочка из функциональщины, функции высшего порядка и т.д., но бред это все, так не пишет никто.

хаскелляторы отложили штанги и укоризненно глядят на тебя

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

Однострочники на питоне выглядят страшно, не спорю. Если хочется красивой работы с простыми структурами данных, лучше взять clojure.

(def names ["John" "James" "Jakob" "Peter" "Janette" "Tom" "Vasya" "Jean" "Juilia" "Heather", "Jeb"])

(doall
(map #(println (apply format "%s and %s follow %s" %))
     (->> names
         (filter #(= \J (get % 0)))
         (partition 3))))
PolarFox ★★★★★
()
Ответ на: комментарий от Virtuos86

так много софта на хаскеле -_-

википедия: «Сегодня Haskell стал языком быстрой разработки надёжных, кратких и корректных программ»

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

К тому же, эта штука прекрасно реализуема на руби.

Лишь потому что там повезло иметь нужный именно для этого высосанного из пальца примера набор функций в стандартной библиотеке. Всё равно что хвастаться, что в питоне веб-сервер в одну строчку пишется.

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