LINUX.ORG.RU

Ruby 1.9.2

 ,


0

0

Ruby 1.9.2 по большей части совместим с 1.9.1 за исключением данных изменений:

  • Множество новых методов.
  • Новый socket API (с поддержкой IPv6).
  • Новые кодировки.
  • Класс Random, в котором доступны различные генераторы случайных чисел.
  • Переписан класс Time, устранена проблема 2038 года.
  • Некоторые улучшения в regexp'ах.
  • $: больше не включает текущую директорию.
  • dl переписан с использованием libffi.
  • Новая библиотека psych, являющаяся обёрткой libyaml, которую можно использовать вместо syck.

Новая версия проходит 99% тестов RubySpec.

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

★★

Проверено: JB ()
Последнее исправление: MuZHiK-2 (всего исправлений: 4)
Ответ на: комментарий от mkfifo

> наверно тебе не стоит обзяснять что __init__ выполняется кажый раз при создании экземпляра?

Она вызывалась и в твоем коде.

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

> вообще — лучше приведи пример для ...

Для тебя, быдлокодеришка, всегда пожалуйста:

class CountingRequestHandler(webapp.RequestHandler): 
	def __init__(self, page, *args, **kwargs):
		super().__init__(*args, **kwargs)
		self.page = page

	def get(self): 
		self.response.headers[u'Content-Type'] = u'text/plain;charset=UTF-8' 
		self.response.out.write(u'Hello Word!\n\n') 
		self.response.out.write(u'*** вы нащёлкали ⌈↻⌋ -- %s раз ***\n\n' % self._counter) 		
		with self.page._lock: 
			self.page._counter += 1 

class MainPage:
    def __init__(self):     
        self.RequestHandler = CountingRequestHandler(self)     
        self._lock = threading.Lock() 
        self._counter = 0 

или еще проще и лучше:

class MainPage(webapp.RequestHandler): 
    _counter = 0
    _lock = threading.Lock()

    def get(self): 
        self.response.headers[u'Content-Type'] = u'text/plain;charset=UTF-8' 
        self.response.out.write(u'Hello Word!\n\n') 
        self.response.out.write(u'*** вы нащёлкали ⌈↻⌋ -- %s раз ***\n\n' % self._counter)
        with self._lock:
            self.__class__._counter += 1 
 
application = webapp.WSGIApplication([(u'/', MainPage())], debug=True) 
ntp
()
Ответ на: комментарий от Lucky

> так мы про ООП или про костыли? запись `class TObject(object): pass`

как бы намекает на то, что к object нового поведения не добавляется.

если костыли заключались только лишь в этот — то можно вздохнуть с облегчением :-D

а ты можешь просто записать вот так:

class TObject:
    pass

class T2Object(TObject):
    pass

и представь что никакого object не существует :-)

.. при этом T2Object действительно не добавляет нового поведения относительно TObject :-)

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

> так мы про ООП или про костыли?

Ты о том, что в класс-родитель нельзя добавить атрибут, и это, по-твоему, бред. А я про то, что для демонстрации этого тезиса ты выбрал класс object - единственный, в который добавлять атрибуты запрещено языком.

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

в первом примере:

self.page = page


с чего ты взял — что в webapp.RequestHandler ЕЩЁ НЕТ служебного члена page ?

..или что его не добавят завтра? разработчики класса webapp.RequestHandler


во втором примере — тоже самое про self._lock ...

откуда уверенность что ты не законфликтовал её с уже существующей переменной _lock внутри webapp.RequestHandler ???


это значит вот так вы пишете программы [наобум тыкая переменными в ЧУЖИЕ классы] — программы, который сегодня идут, а завтра почемуто вдруг начинают выдавать ошибки [после обновления библиотек]....
ясно, ясно, теперь вижу..... :D :D :D


# p.s.: кстате заметим что в примере я передаю не {готовый экземпляр} от субкласса webapp.RequestHandler, а {указатель на конструктор класса}...
...но это не особо важно, так как я обещал не приедераться к деталям :) :)

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

> в инстанс наследника можно динамически добавлять атрибуты, а в инстанс родителя - нельзя. с точки зрения ООП - полный бред.

Тонко намекну:

>>> class MyClass(object):
...     __slots__ = ()
... 
>>> c = MyClass()
>>> c.prop = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'prop'

запись `class TObject(object): pass` как бы намекает на то, что к object нового поведения не добавляется.

В object нового поведения и не добавляется. А вот TObject - совсем другой класс и какое поведение он будет иметь определяется его метаклассом (по умолчанию это метакласс type).

class EsothericMetaclass(type):
	def __new__(metaclass, name, bases, dict):
		if [base for base in bases if isinstance(base, EsothericMetaclass)]:
			return "Hello, World!"
		
		return type.__new__(metaclass, name, bases, dict)

class EsothericClass(object):
	__metaclass__ = EsothericMetaclass

class MyClass(EsothericClass):
	pass

print MyClass

Вопрос на засыпку: MyClass у нас теперь что и как он себя ведет?

Не знаете питон - лучше промолчите, а то пердежом в лужу попахивает.

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

> с чего ты взял — что в webapp.RequestHandler ЕЩЁ НЕТ служебного члена page ?

Мне уже даже не смешно тебя читать, быдлокодер. Ну сделай его private.

class CountingRequestHandler(webapp.RequestHandler):  
   def __init__(self, page, *args, **kwargs): 
      super().__init__(*args, **kwargs) 
      self.__page = page

> это значит вот так вы пишете программы [наобум тыкая переменными в ЧУЖИЕ классы]

Прикинь, питон так устроен. Любое наследование наобум добавляет свои члены к отнаследованным от других классов. Ибо protected нет вообще, а private через __ никто не использует. И да, ООП прикручено сбоку и костылями.

> кстате заметим что в примере я передаю не {готовый экземпляр} от субкласса webapp.RequestHandler, а {указатель на конструктор класса}...

Ну убери во втором случае скобочки, я на вскидку писал, без понятия какой там у гугла API.

application = webapp.WSGIApplication([(u'/', MainPage)], debug=True)

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

ты выбрал класс object - единственный, в который добавлять атрибуты запрещено языком.

ок. давай еще:

>>> i = 0
>>> type(i)
<type 'int'>
>>> class I(type(i)): pass
...
>>> f = lambda: 0
>>> type(f)
<type 'function'>
>>> class F(type(f)): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    type 'function' is not an acceptable base type
за что ООП языке такое костыльное отношение к функциям?

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

> ты выбрал класс object - единственный, в который добавлять атрибуты запрещено языком

Нельзя добавлять в любой встроенный.

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

А вот TObject - совсем другой класс и какое поведение он будет иметь определяется его метаклассом (по умолчанию это метакласс type).

сами напросились:

>>> class EsothericClass(object): 
...    __metaclass__ = EsothericMetaclass 
... 
>>> EsothericClass.__metaclass__
<class '__main__.EsothericMetaclass'>
>>> object.__metaclass__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'object' has no attribute '__metaclass__'
вот у EsothericClass видно, что есть метакласс. а где у object метакласс? опять костыль? ;)

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

> ок. давай еще:

Не, давай ты на первый вопрос ответишь. А то ты хочешь каких-то странных вещей и называешь их отсуствие «костылями».

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

> за что ООП языке такое костыльное отношение к функциям?

Не только к функциям. От большей части из модуля types отнаследоваться нельзя. Но опять же, как и в примере со __slots__ никто не мешает вам запретить наследование и от своих классов через переопределение метакласса. Встроенные классы в этом отношении не уникальны.

вот у EsothericClass видно, что есть метакласс. а где у object метакласс? опять костыль? ;)

А зачем ему переопределять метакласс? Если __metaclass__ явно не переопределен, то автоматически используется type.

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

> Не, давай ты на первый вопрос ответишь.

а где вопрос? ^) про то, что object() , это по сути, фабрика специальных костылей, которые в общем-то нужны лишь на уровне С-шного интерфейса? http://tech.blog.aknin.name/2010/05/12/pythons-innards-objects-101/ . как такое недоразумение, с точки зрения наследования, смотрится в рамках языка, разработчиков не волнует. твоя очередь ;)

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

> Ну хорошо, приведите другой общепринятый вариант изменения атрибута у класса.

Да мне вообще изменение атрибутов класса кажется сомнительной техникой программирования для повседневных задач. Какая-то Ява получается.

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

>> Не, давай ты на первый вопрос ответишь.

а где вопрос?

Почему то, что в класс-родитель нельзя добавить атрибут является «бредом с точки зрания ООП»? Если что, существуют статически типизированные ООП-языки, и там в готовый класс вообще нельзя добавить атрибут. Они все бредовы?

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

> Да мне вообще изменение атрибутов класса кажется сомнительной техникой программирования для повседневных задач.

Т.е. static члены класса в Си++, Си#, Джаве и т.д. вы тоже не используете? Необычно, конечно, но такое мнение тоже имеет право на существование.

Можно поинтересоваться как вы на питоне синглетон делаете?

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

> static члены класса в Си++, Си#, Джаве и т.д. вы тоже не используете?

Стараюсь. Класс должен быть самодостаточным и по своей воле не менять ничего за пределами self.

Можно поинтересоваться как вы на питоне синглетон делаете?

Не надо так официально... а синглтонов я на Питоне не делаю. Они и вообще признаны антипаттерном (для тех, кого заботит pattern compliance), и просто не нужны, когда есть функции.

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

> Они и вообще признаны антипаттерном (для тех, кого заботит pattern compliance), и просто не нужны, когда есть функции.

Принято. Хотя атрибуты класса изредка бывают очень полезными.

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

Во, извращаться так извращаться:

class Moo
	def x
		y
	end
	private
	def y
		999
	end
end

class Foo
	def initialize
		@moo = Moo.new
	end
	def method_missing(method, *args)
		@moo.send(method, *args)
	end
	def y
		100500
	end
end

f = Foo.new
puts f.y      # 100500
puts f.x      # 999
puts f.blah   # undefined method error
Deleted
()

А как будет выглядеть на руби следующий кусок кода?

class Foo(object):
    def __init__(self, value):
        self.value = value


# class method
Foo.bar = lambda self: self.value + 1

# class static method
Foo.sbar = staticmethod(lambda: 'boo')

foo = Foo(10)

# instance method
foo.baz = lambda: foo.value + 5

print Foo.sbar()
print foo.bar()
print foo.baz()
baverman ★★★
()
Ответ на: комментарий от ntp

>> кстате заметим что в примере я передаю не {готовый экземпляр} от

субкласса webapp.RequestHandler, а {указатель на конструктор

класса}...



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

какой там у гугла API.

хорошо убрал... но появилась новая КОНЦЕПТАУЛЬНАЯ проблемма:

это то что когда я использовал self._counter и self._lock — я использовал переменные-члены своего класса (MainPage)

экземпляры класса MainPage — имеют/могут-иметь время жизне больше чем время жизне экземпляров подклассов-webapp.RequestHandler

(потомучто экземпляры подклассов-webapp.RequestHandler создаём не мы, а СТОРОННИЙ API... и когда он их захочет создать или удалить — решать ему а не нам. я лишь передаю этом API — указатель на конструктор)

но ТЫ предлагаешь использовать self.__class__ <-- для переменных которые не должны удаляться после удаления экземпляров подкласса-webapp.RequestHandler

.....

другими словами ты ЯВНО указываешь на ГЛОБАЛЬНЫЕ переменные

использовать глобальные переменные — значит это по твоему не быдлокодертсово, да? :-) :-)

(хорошо.. мой объект main_page — тоже глобален.. НО! во первых он глобален в единичном случае.. а во вторых всегда можно изменить программу так чтобы этих объектов было несколько, при случае)

твои же self.__class__-переменные — будут глобальны навсегда и неповоротно!

вобщем — из нас твоих быдлокодер — это ты... так как если ты подумаешь хорошенько — то поймёшь что в случаях — когда функция требует указатель на УНИКАЛЬНЫЙ класс/конструктор (а не на экземпляр) — то при необходимости предоставлении такого конструктора никакая другая конструкция кроме {замыкания внутреннего класса} не прокатит [или прокатит, но выглядеть будет как костыль, как например предложанные тобой глобальные переменные]

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

Смотря что именно ты хочешь получить :) Это?

class Foo
	def initialize(value)
		@value = value
	end
	def bar
		@value += 1
	end
	def self.sbar
		'boo'
	end
end

foo = Foo.new(10)

class << foo
	def baz
		@value += 5
	end
end

puts Foo.sbar # boo
puts foo.bar  # 11
puts foo.baz  # 16
Deleted
()
Ответ на: комментарий от Deleted

> Во, извращаться так извращаться:

да кстате.... есть разные мысли по поводу того чтобы «улучшить» наследование.... :-)

...например [написать специальный программный карказ, на основе метаклассов] чтобы в создаваемых классах — во время наследования при описании новых методов — можно было бы указывать ЯВНО: что это --{ «новый метод» или «перегрузка старого» }

если метод описывается как «новый» то поведение методов его РОДИТЕЛЬСКИХ-классов не меняется! для них нового метода какбы НЕ существует... даже если его название совпадает с существующим :-)
[тоесть ПРЕДКИ — не видят «новый» метод в своей области видиния, а обращаются к «старому»]

зато «новый метод» виден для текущщего_классв и его дочерних_классов. правда для них — пропадает из поля зрения «старый метод»

а если метод описывается как «перегрузка старого» — то происходит перегрузка того «старого» метода который какраз-видят РОДИТЕЛЬСКИЕ-классы

.....
....вобщем вариантов поизвращаться много разных :-)

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

>если метод описывается как «новый» то поведение методов его РОДИТЕЛЬСКИХ-классов не меняется! для них нового метода какбы НЕ существует...

Для private методов такое было бы неплохо :}

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

ээээ.... ды private то чо перегружать ... на то он и private.. его итак никто «какбы не видит» кроме текущщего класса

я вообще про protected имел ввиду

хотя в терминах Python — protected это «_*» а private это «_*__*» — и всё это одновременно и public — такчто эээээээ говорить про private/protected/public — как-то не приходиться :-) :D :D :D

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

В терминах руби, говорят, всем без разницы — предпочитают не пользоваться вообще (не знаю, врут или нет, проверять мне пока лень), ввиду того, что при желании всё равно можно ногу отстрелить через send() :)

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

Выдыхай.

но ТЫ предлагаешь использовать self.__class__

Я специально показал несколько способов. Это лишь один из них. Широко, кстати, используемый (как я выше уже писал все питоновские ActiveRecord-style ORM его используют для определения порядка полей у моделей).

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

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

И да, глобальные переменные (как и goto) имеют свою область применения.

когда функция требует указатель на УНИКАЛЬНЫЙ класс

Указатели на класс в питоне? А i = 1 - это наверное указатель на int?

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

никакая другая конструкция кроме {замыкания внутреннего класса} не прокатит

Я тебе специально показал 2 способа. Если в данном случае не подходит наследование, то используй композицию. А вот замыкания не используй. Не надо.

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

> вот замыкания не используй. Не надо.

ладно, хрен с ним.. с замыканием...

можно задекларирвоать функцию которая будет инициализировать_новый_экземпляр и передавать указатель на эту функцию (вместо указателя на подкласс)

тоесть — дествительно.. если не хочешь использовать замыкания — всегда можно найти способ их не использовать

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

> Указатели на класс в питоне? А i = 1 - это наверное указатель на int?

чото непонимаю в чём прикол этой шутки :-)

my_int = int <-- ну да — это указатель на класс

i = 1
type(i) <-- тоже указатель на класс

не нравиться слово «указатель» ?.. ну ладно.. замени на слово «ссылка» :-)

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

> Походу, место в топе крутизны обратно пропорционально месту в топе практической используемости.

А ты как думал? Практическое использование - это энтерпрайз, а энтерпрайз всегда, и по хорошей причине, выбирает наиболее популярный и наименее рискованный (что одно и то же) вариант. Техническая сторона - дело десятое.

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

Это?

То есть, если где-то уже есть класс Foo, то bar и sbar к нему добавятся? Что ж, достойное решение за неимением first-class функций. Хотя довольно-таки неявное.

А если так:

class Foo(object):
    pass

foo = Foo()

# instance class patching
foo.__class__.bar = lambda self: 'foo::bar'

print foo.bar()

То есть класс заранее неизвестен.

baverman ★★★
()
Ответ на: > медленный, только что от paranormal

>Ruby — якобы очень медленный язык. Этот миф возник в связи с распространением ruby в Эстонии в 19 веке до н. э.

А что, если для едущих на велосипеде черепаха - медленная, то для едущих на мотоцикле черепаха будет быстрее? :D

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

>Походу, место в топе крутизны обратно пропорционально месту в топе практической используемости.

Дык. Так и есть же :)

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

>И таки да, класс Foo меньше, чем Moo :)

Если Foo наследуется от Moo, то Foo по определению больше. Ибо он включает в себя Moo.

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

> Если Foo наследуется от Moo, то Foo по определению больше. Ибо он включает в себя Moo.

не согласен. наследование отражает отношение обобщения: класс - подкласс. поэтому Foo, будучи подклассом Moo, — меньше. в более строгой терминологии класс-наследник именуется subclass, а родительский класс — superclass. очевидно, что subclass < superclass ))

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

>очевидно, что subclass < superclass

Не очевидно. Это отражение иерархии, но не размера.

Очевидно, что функционал субкласса заведомо больше функционала суперкласса. Очевидно также, что по объёму кода сравнение неуместно. Так что по единственному видимому мной объективному критерию сравнения субкласс получается больше суперкласса.

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

>> очевидно, что subclass < superclass

Не очевидно. Это отражение иерархии, но не размера.

«<» - это как бы математический символ «является подмножеством».

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

>То есть, если где-то уже есть класс Foo, то bar и sbar к нему добавятся?

Ну так класс только один может быть с определённым именем. Если нужно несколько, то модули. Соответственно, указываешь полный «путь».

instance class patching

То есть класс заранее неизвестен.



Ты хочешь что б все объекты класса получили новый метод или только один, foo?

Если 1ое, то foo.class.class_exec do и вперёд как обычно, если второе, то пример был выше с class << foo.

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

Это и сейчас можно сделать, через алиасы к текущим методам :) В принципе, оно только 1ой буквой класса не даёт использовать что-то кроме A-Z а в остальном, хоть метод на русском языке называй.

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

Ладно, уболтал. Признаю альтернативный вариант имеющим право на жизнь :D

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