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)

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

О, а голимая строка знает об объектах входящих в контейнер все, лол.

Строка знает что она строка и будет склеивать с собой только себе подобных.

в контейнер все, лол.

Уясни уже наконец, в определении операции склеивания строк нигде нет понятия контейнера.

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

О, расскажи нам о них!

а что, прикольный был пример

"-".join([1,2,3])
кто бы мог подумать, что оказывается надо
"-".join("{0}".format(n) for n in [1,2,3])
Почему нельзя нормально?)
[1,2,3].join '-'

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

Лол. Она и не знает.

In [1]: l=[1, 2, 3]

In [2]: '-'.join(l)
----------------------
TypeError: sequence item 0: expected str instance, int found

In [3]: '-'.join(map(str, l))
Out[3]: '1-2-3'

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

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

"-".join(«{0}».format(n) for n in [1,2,3])

Кому надо писать именно так? Выше же приводили примеры:

"-".join([str(n) for n in [1, 2, 3]])
"-".join(map(str, [1, 2, 3]))

Почему нельзя нормально?)

[1,2,3].join '-'

А почему это нормально? Отсуствие скобок при вызове метода (в PL/I хотя бы CALL писали), какая-то факинг мэджик в преобразовании из числа в строку.

tailgunner ★★★★★
()
Ответ на: комментарий от special-k
"-".join("{0}".format(n) for n in [1,2,3])

так надо только в твоем воспаленном мозге

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

О, расскажи нам о них!

ООП в питоне - это бред. Без инкапсуляции, без переменных объекта (и класса), и что самое поразительное, с общими методами для класса и его объектов (такого даже в js нет).

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

Можно подумать в руби есть инкапсуляция

2.1.0 :001 > class Cls
2.1.0 :002?>   private
2.1.0 :003?>     def f
2.1.0 :004?>       puts 'There is no encapsulation!'
2.1.0 :005?>     end
2.1.0 :006?>   end
 => :f 
2.1.0 :007 > Cls.new.f
NoMethodError: private method `f' called for #<Cls:0x00000003ddd008>
	from (irb):7
	from /home/victor/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'
2.1.0 :008 > Cls.new.send(:f)
There is no encapsulation!
 => nil 

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

Отсуствие скобок при вызове метода

пиши\

факинг мэджик

to_s? Это называется утиная типизация, точно та же хрень применяется в питоновом join, только чуть иначе. Разница в синтаксисе, в обили всего лишнего, уменьшающего понимание приходящего. Тут же вложенность вижу я, а если, не дай боже, это будет фильтр с лямбдой, а не массив, или еще более сложное преобразование - мрак это будет.

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

ООП в питоне - это бред.

Только с точки зрения Руби-фанбоя.

Без инкапсуляции

Кто-то путает инкапсуляцию и контроль доступа? ЕМНИП, его нет, например, в Smalltalk.

без переменных объекта (и класса)

Как же без, когда с.

и что самое поразительное, с общими методами для класса и его объектов (такого даже в js нет).

Судя по тому, что я даже не понял о чем ты, у Python реально серьезная проблем.

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

факинг мэджик

ох мля... а то в питоне нет вызова __str__

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

Отсуствие скобок при вызове метода

пиши

Ыыы... то есть можно писать, а можно не писать? Этот ваш Руби - средство самовыражения кодеров (именно кодеров).

факинг мэджик

to_s? Это называется утиная типизация

Неявные вызовы методов - это ни разу не утиная типизация. Это факинг мэджик (или coercion, если уж нужен технический термин).

а то в питоне нет вызова __str__

И это тоже плохо. Но в Python неявный вызов выполняется в основном при интерполяции строк для %s.

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

а теперь посмотри на твои любимые ML-подобные )

Там статическая типизация, так что им можно простить.

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

Аналогия-куртизанка

Можно подумать в самолёте кто-то заботится о безопасности пассажжиров. Проносишь оружие, стреляешь в ногу.

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

Это называется утиная типизация, точно та же хрень применяется в питоновом join, только чуть иначе. Разница в синтаксисе...

У питоновского join() типизация строгая и разница не только в синтаксисе. Не неси херни.

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

В Ruby Array это именно массив строк?

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

Но можно гарантировать хотя бы в рантайме. И питон это делает, как видишь из своего же примера.

Что именно гарантирует питон?

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

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

Конкатенация это только свойство строк.

А это что? Конкатенация — это не только свойство строк.

В Py эту ситуацию обработали достаточно корректно, операция join() берёт на вход итератор за которым может быть не только массив и не только контейнер.

В документации указана следующая сигнатура — str.join(iterable). Дано определение iterable.

Мне обещают, что если я передам этому методу iterable, то все будет в порядке. И когда я передаю ему [1,2,3], валидный iterable, я начинаю чувствовать себя несколько обманутым.

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

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

У руби куча обманов и похлеще.

2.1.0 :007 > (1..3) === 2
 => true 
2.1.0 :008 > 2 === (1..3)
 => false
Почему == симметричный, а === несимметричный? Почему такое поведение не отражено в сигнатуре === ?

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

Почему == симметричный, а === несимметричный?

Потому что это два разных метода.

Почему такое поведение не отражено в сигнатуре === ?

Потому что это тоже два разных метода.

(1..3).method(:===).owner  #=> Range
2.method(:===).owner       #=> Fixnum
Это поведение отражено в сигнатурах #=== и #===.

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

типизация строгая

да ладно))))

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

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

средство самовыражения

людей, я бы сказал..

Неявные вызовы методов - это ни разу не утиная типизация.

Да что ты говоришь.

И это тоже плохо.

Что здесь плохого, ты не можешь все действия выполнить явно, это вообще противоречит использованию методов. Вызывая любой метод ты вызываешь что-то неявно. Код не должен быть явным, код должен быть понятным, и такой вот факап: "-".join("*{0}*".format(n) for n in [1,2,3]) не нужен. Да, явно, а что толку, когда [1,2,3].join понятно _всем_.

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

99% правильно или 99% удобно

Известная проблема: быть более «правильным» или более «удобным».

Не вызывать str() для элементов join - это «логично» и «правильно».

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

Питон между «удобно» и «правильно» чаще выбирает «правильно». Руби чаще выбирает «удобно».

На фоне perl, php и JavaScript и руби и питон оба и правильные и удобные.

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

Поведение join тоже отраженно в его сигнатуре.

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

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

for i in xrange(3):
    for i in xrange(3):
        print "inner: %d" % i
    print "outer: %d" % i

# inner: 0
# inner: 1
# inner: 2
# outer: 2
# inner: 0
# inner: 1
# inner: 2
# outer: 2
# inner: 0
# inner: 1
# inner: 2
# outer: 2
На Ruby это выглядит так и ничего не ломается:
3.times do |i|
    3.times do |i|
        puts "inner: #{i}"
    end
    puts "outer: #{i}"
end

# inner: 0
# inner: 1
# inner: 2
# outer: 0
# inner: 0
# inner: 1
# inner: 2
# outer: 1
# inner: 0
# inner: 1
# inner: 2
# outer: 2

Или:

# $ cat b 
# bar

with open("a", "w") as f:
    f.write("foo")
    
    with open("b") as f:
        line = f.readline()
    
    f.write(line)

# Traceback (most recent call last):
#   File "...", line NN, in <module>
#     f.write(line)
# ValueError: I/O operation on closed file

# $ cat a 
# foo
На Ruby это делают так:
# $ cat b 
# bar

File.open('a', 'w') do |f; line|
    f.puts 'foo'
    File.open('b') do |f|
        line = f.readline
    end
    f.puts line
end

# $ cat a
# foo
# bar
Что же касательно замыканий, реализуя-ка counter на замыканиях в гвидопараше (без использования nonlocal костыля). Вот так вот должен работать counter:
def counter
    i = 0
    ->() { i += 1 }
end

f = counter

3.times do |_|
    puts f.()
end

# 1
# 2
# 3
Что бы не было недоразумений, тебе, как знающему Lisp, нужно сделать так на гвидоговне:
(defun counter (&aux (i 0))
  (lambda () (incf i)))

(iter (with c = (counter))
      (repeat 3)
      (collect (funcall c))) ; (1 2 3)
Я думаю этого достаточно для того, чтобы при встрече обоссать любого гвидоговноеда. Или есть ещё какие-то сомнения? Я могу продолжить кормить говном, ибо в гвидобейсике его пруд пруди...

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

2.1.0 :001 > for x in [1, 2, 3] 2.1.0 :002?> p x 2.1.0 :003?> end 1 2 3 => [1, 2, 3] 2.1.0 :004 > p x 3 => 3

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

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

Пфф. Это эпический факап? Бозе мой, бозе мой.

На Ruby это выглядит так и ничего не ломается:

Этот пример должен был продемонстрировать, что «факап» мешает только в специально придуманных случаях или что?

Что же касательно замыканий, реализуя-ка counter на замыканиях в гвидопараше (без использования nonlocal костыля)

Ну, например:

def counter(initval):
  def incr():
   counter.val += 1
   return counter.val
  counter.val = initval
  return incr
c1 = counter(0)
print c1()
print c1()

тебе, как знающему Lisp

Я не знаю CL. Только Схему в рамках SICP.

Я думаю этого достаточно для того, чтобы при встрече обоссать любого гвидоговноеда

Я думаю, что мощности твоего баттхерта достаточно, чтобы зажечь небольшую звезду.

Я могу продолжить кормить говном

Пока что ты им плюешься. Продолжай, пожалуйста.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от deadlock
2.1.0 :011 >   l = -> { puts 'В раби говна больше. Приятного аппетита!' }
 => #<Proc:0x000000030d7e58@(irb):11 (lambda)> 
2.1.0 :012 > l[]
В раби говна больше. Приятного аппетита!
 => nil  
anonymous
()
Ответ на: Упс от anonymous

Упс

Хуюпс. for .. in в Ruby - это legacy говно, которое никто не использует. Итерация по коллекции для сайд-эффектов осуществляется методом each, а тех, кто использует for .. in просто убивают на месте.

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

Ну, например:

Охуеть замыкание. И что ты тут замкнул, дружище? :) Ты пропатчил функцию-объект, тем самым вытащив наружу контекст. Именно так грязные гвидоопущи и поступают, потому что им деваться некуда.

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

Он замкнул остатки твоего маленько мозга...

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

Пфф. Это эпический факап? Бозе мой, бозе мой.

Пфф. Это он и есть. Это рассадник багов и недоразумений. Фактически, чтобы избежать багов придётся всегда разносить логически связанный код на мелкие функции, тем самым засерать пространство имён ненужным фуфлом и уменьшать читаемость. И даже в этом случае нет никакой гарантии.

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

Охуеть замыкание

Тебе нужен был счетчик - вот тебе счетчик.

Ты пропатчил функцию-объект, тем самым вытащив наружу контекст

Ты настолько тупой, что не понял примера? Там «пропатчить» можно incr, никаких проблем.

def counter(initval):
  def incr():
   incr.val += 1
   return incr.val
  incr.val = initval
  return incr
c1 = counter(0)
c2 = counter(0)
print c1()
print c1()
print c2()

incr - локальный объект, имею право «патчить».

Впрочем, после твоего «хуюпс, это легаси говно» твой запрет использовать nonlocal выглядит слегка лицемерным, так что получи и распишись:

def counter(val):
  def incr():
   nonlocal val
   val += 1
   return val
  return incr

Пфф. Это эпический факап? Бозе мой, бозе мой.

Пфф. Это он и есть.

Самое эпичное здесь - попытки делать на основе этой мелочи выводы глобального масштаба и глобальной глупости.

грязные гвидоопущи

Без примеров кода - беспомощное кукареканье.

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

Впрочем, после твоего «хуюпс, это легаси говно» твой запрет использовать nonlocal выглядит слегка лицемерным, так что получи и распишись

Пожалуй, лучшая фраза в этой теме. Два чая автору.

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

Зачем в языке конструкция которую никто не использует?

Тебе же сказал я, что legacy, грязный ты сектант. В твоей секте хуевертят и не учитывают обратную совместимость, и поэтому теперь есть 2 поддерживаемые версии 2.7 и 3.x.

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

Тебе нужен был счетчик - вот тебе счетчик.

Мне нахуй счётчик не нужен. Мне нужен счётчик на замыканиях; научись уже внимательно читать.

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

Ты настолько тупой, что не понял примера?

Я понял только то, что ты сходу не смог правильно написать тривиальную вещь, прихуячив к интерфейсной функции ссанай val, фактически сделав из counter-а сраный singleton. Но ты не волнуйся, обычно гвидодрочеры все тупые. Ты ещё молодец :)

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

Самое эпичное здесь - попытки делать на основе этой мелочи выводы глобального масштаба и глобальной глупости.

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

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

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

Да нет, использовать то можно. Только вот третий бейсик до сих пор широко не распространён, да и nonlocal выглядит очень по-уебански.

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

Мне нужен счётчик на замыканиях; научись уже внимательно читать.

Теперь у тебя есть два. Набирай в рот новую порцию говна и плюйся снова.

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

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

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

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

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

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

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