Re: get_or_create как правильно назвать
От: fmiracle  
Дата: 10.12.08 12:20
Оценка: 1 (1) +2
Здравствуйте, Kluev, Вы писали:

K>чем бы заменить слишком длинное имя item_get_or_create?


Да ничем ты ее не заменишь, не потеряв понятности.
Хотя если это коллекция однотипных элементов, то я бы убрал "item_", оставив просто add, get, get_or_create

Последний, являющийся прямой комбинацией get+add, тоже можно безболезненно убрать, используя функцию-хелпер там, где она нужна. Но это уже зависит от приложения в целом, может у вас полезно иметь ее именно в классе.
Re[3]: get_or_create как правильно назвать
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.12.08 13:12
Оценка: +2 -1
Здравствуйте, Anpek, Вы писали:

A>Здравствуйте, fmiracle, Вы писали:


A>А нельзя в get ввести булевский аргументик "создавать если нет?" ?


Дополнительная косвенность — зло
Будут потом пихать туда какой-нибудь левый флаг и придётся дополнительно разбираться, чтож это за флаг, зачем он нужен и т.п.
Мелочь, но понимаемость кода уменьшает имхо.
(Ну и вообще сцепление по управлению не очень рекомендуют использовать, если уж функция что-то делает дак пусть делает, а не делает что-то что зависит от фазы луны)
Re[4]: get_or_create как правильно назвать
От: Undying Россия  
Дата: 15.12.08 04:34
Оценка: +2 -1
Здравствуйте, _FRED_, Вы писали:

_FR>Оригинально было просто "ensure", что встречается довольно часто.


Просто "ensure" вообще смысловой нагрузки не имеет, такое название можно только заучить, догадаться что делает метод с таким названием невозможно. get_or_create заучивать не надо, то что делает метод с таким названием интуитивно понятно.
Re[17]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 16:24
Оценка: 66 (2)
Здравствуйте, Lloyd, Вы писали:

L>Ты можешь просто и доходчиво объяснить, почему не-бросание исключения было ошибкой?


Для начала: я пока нигде (в этом топике) не утверждал о том, что "не-бросание исключения было ошибкой". Мы стали спорить о том, что "стандартнее" и о том, что Hashtable: пример плохого, "непродуманного", контейнера. Вспомни своё сообщение
Автор: Lloyd
Дата: 15.12.08
:

U>>Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу,
_FR>Что это за стандарт? Зависит только от библиотеки.
Широко-распространенные бибилиотеки де-факто и задают стандарт.
За примером далеко ходить не надо: Hashtable из .Net Framework-а.


Я понимаю так:
U>>>По стандарту надо бросить
_FR>>Что это за стандарт?
L>Hashtable

То есть это тебе с Undying спорить надо было, о том, чем же хороша и стандартна Hashtable. Я-то как раз хотел показать, что все делают по-разному (не факт, что хорошо, но — по разному).

Возвращаясь к нашим тараканам: теперь я скажу, что "не-бросание исключения было ошибкой", вернее, следствием ошибки проектирования Hashtable.

Дело не в "небросании", а целиком в том, что нельзя сразу и получить объект и узнать, что его там нету. Только двумя запросами. Это способствует тому, что во многих местах игнорируются ситуации, когда ключа, с которым код обратился к словарю в словаре не оказалось. В дизайне IDictionary<> надо всегда помнить, что нужного ключа может и не быть, а не то сразу получишь KeyNotFound. При дизайне Hashtable — ни о чём не говорящий NullReference.

Например, как выглядит код, который, при необходимочти возвращает данные из кэша:
private Hashtable cache…

object GetService(string name) {
  object servive = cache[name];
  if(servive == null) { // (*)
    servive = CreateService(…);
    cache.Add(name, servive);
  }//if
  return service;
}

(*) Главная проблем в том, что можно проверить, а можно и не проверить. И о том, что не проверил, ты узнаешь неизвестно где в самый неподходящий момент. Хорошее проектирование предполагает обраружение ошибки как можно ближе к месту её, ошибки, возникновения. IDictionary<> эту проблему решает на корню. Ошибиться так же можно и с ней, но результат будет совсем другой.

Дизайн IDictionary<> позволяет, при желании, работать по-старому:
static class Extensions
{
  public static TItem GetOrDefault<TKey, TItem>(this IDictionary<TKey, TItem> source, TKey key, TItem defaultValue) {
    if(source == null) {
      throw ewn ArgumentNullException("source");
    }//if

    TItem item;
    return source.TryGetValue(key, out item) ? item : defaultValue;
  }
  
  public static TItem GetOrDefault<TKey, TItem>(this IDictionary<TKey, TItem> source, TKey key) {
    return source.GetOrDefault(key, default(TItem));
  }
}

И даже здесь удачно подобранное имя "хелпера" (выделено жирным) не позволяет "случайно забыть" о том, что же происходит. А вот на Hashtable так же производительно, как в IDictionary<> реализовать TryGetValue нельзя.



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

Как альтернатива TryGetValue, можно было бы либо
class Hashtable : …
{
  public static readonly object NotFound = new object();
  …
}

в геттере возвращать заместо null этот самый "special value" NotFound, что было бы уже лучше, но так же спорно. Можно было бы возвращать из индексера некий
struct Option
{
  public bool HasValue { get; }
  public object Value { get; }
}

но опять, же, ИМХО, TryGetValue выглядит приятнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re: get_or_create как правильно назвать
От: Andrei F.  
Дата: 10.12.08 10:54
Оценка: -2
Здравствуйте, Kluev, Вы писали:

K>чем бы заменить слишком длинное имя item_get_or_create?


ensure, force_get
кстати, порядок слов у вас неестественный для английского языка
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[6]: get_or_create как правильно назвать
От: Undying Россия  
Дата: 15.12.08 11:52
Оценка: +2
Здравствуйте, _FRED_, Вы писали:

U>> но часто бывает, что от Dictionary требуется безопасное поведение, т.е. нужно, чтобы при обращении по несуществующему ключу возвращался null, для чего пишется метод get_or_default(T key).


_FR>Нет, по-нормальному делается TryGetItem, которая или получить результат или узнать, что результата нет. get_or_default не даёт информации о результате и, в большинстве случаев, для словаря, бесполезна.


На практике логике выполнения программы в 99% случаях безразлично равно ли значение по ключу null или ключа в словаре нет вообще. Соответственно использование функции DictionaryHlp.GetValueOrDefault (или dictionary.FindObject на extension) логике программы никак не мешает, зато и лаконичнее и безопаснее в использовании.

_FR>Обычно, методы с префиком "ensure" смотрят: выполняется ли какое-либо условие, и если не выполняется, делают так, что бы условие выполнялось. Если условием является наличие элемента в контейнере, то что будет делать метод ensure, ИМХО, очевидно.


И как понять, что ensure проверяет именно наличие элемента в коллекции, а не что-то другое? Ладно бы еще метод ensure_get назывался, там хоть какой-то намек есть в названии.
Re: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 12:14
Оценка: +2
Здравствуйте, Kluev, Вы писали:

K>чем бы заменить слишком длинное имя item_get_or_create?


Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.
Так что бей на два метода и не ошибешься.
Re[4]: get_or_create как правильно назвать
От: Erop Россия  
Дата: 15.12.08 16:37
Оценка: +1 :)
Здравствуйте, Andrei F., Вы писали:

AF>

AF>collection.EnsureItem(val) — ясно и однозначно понятно любому, кто знает английский

Могу предложить по крайней мере две трактовки:
1) аналог std::vector::at, в отличии от collection.Item, возможно являющегося аналогом std::vector::operator []
2) Выставляет этому элементу флажок уверенности в нём. Типа элементы бывают гарантированные и негарантированные...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[24]: get_or_create как правильно назвать
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.12.08 00:22
Оценка: 18 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>Когда Hashtable возвращает null, и на основании этого кажется, что словарь не нашёл значение, код тоже кажется очевидным. Да?


Нет. Я говорил исключительно про -1 у IndexOf.

_FR>В том, что можно не сделать проверку и узнать об этом неизвестно когда, если вообще узнать.


Такое и с TryGetValue лехко можно учудить.
... << RSDN@Home 1.2.0 alpha 4 rev. 1127 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[2]: get_or_create как правильно назвать
От: Anpek  
Дата: 10.12.08 12:23
Оценка: -1
Здравствуйте, fmiracle, Вы писали:

А нельзя в get ввести булевский аргументик "создавать если нет?" ?
Re[4]: get_or_create как правильно назвать
От: Undying Россия  
Дата: 12.12.08 04:39
Оценка: +1
Здравствуйте, Andrei F., Вы писали:

U>>ensure_get, т.е. "гарантированно получить" это несколько лучше, из такого названия можно понять, что элемент будет получен в любом случае, но непонятно будет ли получаемый элемент добавлен в коллекцию в случае его отсутствия или нет.


AF>Не вижу смысла в таком странном поведении.


Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу, но часто бывает, что от Dictionary требуется безопасное поведение, т.е. нужно, чтобы при обращении по несуществующему ключу возвращался null, для чего пишется метод get_or_default(T key). Естественно вызов этого метода ничего в Dictionary добавлять не должен. Соответственно при использовании ensure_get непонятно скрывается ли под ним get_or_create или get_or_default.
Re[2]: get_or_create как правильно назвать
От: Undying Россия  
Дата: 15.12.08 12:01
Оценка: +1
Здравствуйте, Andrei F., Вы писали:

K>>чем бы заменить слишком длинное имя item_get_or_create?

AF>ensure, force_get

Собственно принцип такой, если мы по каким-то причинам считаем необходимым написать метод со сторонним эффектом, то смысл стороннего эффекта должен присутствовать в названии метода. В данном случае сторонним эффектом является создание элемента, а не его гарантирование или принуждение, поэтому в названии метода должно присутствовать слово create (или его точный синоним), а не слова связанные со сторонним эффектом метода весьма иносказательно.
Re[7]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 12:17
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

U>>>Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу,

_FR>>Что это за стандарт? Зависит только от библиотеки.
L>Широко-распространенные бибилиотеки де-факто и задают стандарт.
L>За примером далеко ходить не надо: Hashtable из .Net Framework-а.

Не очень удачный пример неудачно спроектированного контейнера. Чего с него пример брать? Взгляни на более продуманный IDictionary<,>.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[9]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 12:58
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>>>Широко-распространенные бибилиотеки де-факто и задают стандарт.

L>>>За примером далеко ходить не надо: Hashtable из .Net Framework-а.

_FR>>Не очень удачный пример неудачно спроектированного контейнера. Чего с него пример брать? Взгляни на более продуманный IDictionary<,>.


L>С чего ты взял, что он более продуманный? Он просто другой.


Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.

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

А в "наследство" нам достались такие вот хитрости:
Hashtable map = …;
var count1 = map.Count;
var item = map[key];
map[key] = item;
var count2 = map.Count; // count2 может отличаться от count1.


У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).

Кстати, ни в стл::мап, ни в МФЦ::ЦМар нету такой функциональности, что бы по отсутствующему ключу возвращать что-то специальное. Дизайн самик контейнеров сделан так, что этот вопрос не стоит. А в Hashtable стоит. Вернее, стоял. До появления первых бет второго фреймворка, когда стало ясно, что всё вскоре будет по-другому и симпотичнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:06
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Кстати, ни в стл::мап,


Э, нет, эти

If the argument key value is not found, then it is inserted along with the default value of the data type.

Тьфу!
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[3]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:27
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>В данном случае сторонним эффектом является создание элемента, а не его гарантирование или принуждение, поэтому в названии метода должно присутствовать слово create (или его точный синоним), а не слова связанные со сторонним эффектом метода весьма иносказательно.



collection.EnsureItem(val) — ясно и однозначно понятно любому, кто знает английский
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[15]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 15:21
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>>>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".

L>>>Я так и не понял, напугали их или нет в итоге?

_FR>>Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.


L>А это наверное злой хакер написал, укравший твой парол? Вот ведь подлец!

L>Я определён: "хитрости" могли бы "отпугнуть индусов".


Ага, как обычно скатились к буквам

Можешь считать, что "хитрости" бывают первого и второго рада.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[16]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 15:27
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Можешь считать, что "хитрости" бывают первого и второго рада.


Ладно. Ты можешь просто и доходчиво объяснить, почему не-бросание исключения было ошибкой?
Не прибегая к индусам, синхронизации и неспособностям твоих коллег понять "сложные идиомы"?
Re[18]: get_or_create как правильно назвать
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.12.08 22:44
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>Как альтернатива TryGetValue, можно было бы либо

_FR>
_FR>class Hashtable : …
_FR>{
_FR>  public static readonly object NotFound = new object();

Нафик нафик. Никак вон с DBNull размахаться не получается :)

_FR>[c#]
_FR>struct Option
_FR>{
_FR>  public bool HasValue { get; }
_FR>  public object Value { get; }
_FR>}
_FR>


Этот вариант уже вполне нормален, но в большинстве случаев синтаксически немножко более избыточен, чем TryGetValue. Оба этих варианта легко переходят один к другому при помощи простеньких статических хелперов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[20]: get_or_create как правильно назвать
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.12.08 09:58
Оценка: +1
Здравствуйте, _FRED_, Вы писали:

_FR>ИМХО, лучше чем null.


Вот даже и не знаю, какое из двух кривых решений лучше.

_FR> И не хуже, чем -1 в IList<T>.IndexOf


Хуже. Потому что -1 того же типа, в отличие от.
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[2]: get_or_create как правильно назвать
От: Critical Error ICQ: 123736611
Дата: 17.12.08 03:55
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.

L>Так что бей на два метода и не ошибешься.

Согласен, хотя я сам и сделал в аналогичной ситуации 3 метода, но сейчас всеже склоняюсь к двум. Но у меня особый случай — использую паттерн многопточности SWMR и операции чтения должны быть явно отделены от операций записи, иначе получаем лишние блокировки в ненужных местах...

А метод на самом деле очень полезный. Как альтернативу думаю сделать чтото вроде внешней функции GetOrCreate(map, key). Внешние функции хоть и длинные, но это не напрягает, вот странное дело.

ЗЫ: Я таки придумал как коротко обозвать этот метод: goc_item(keys...) (goc == сокращение от Get Or Create).
get_or_create как правильно назвать
От: Kluev  
Дата: 10.12.08 10:25
Оценка:
Привет всем.
Решил навести порядок в именах, не могу подобрать хорошеее и правильное название для функции.

Имеем:
Item* item_add(keys...); // создает новый элемент в контейнере в соотвестивии с ключом (или ключами) keys
Item* item_get(keys...); // возвращает элемент по keys или NULL
Item* item_get_or_create(keys...); // возвращает существующий элемент если он есть или создает новый


чем бы заменить слишком длинное имя item_get_or_create?
Re[2]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 10.12.08 12:59
Оценка:
Здравствуйте, Andrei F., Вы писали:

И с чем несогласны несогласные?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: get_or_create как правильно назвать
От: Erop Россия  
Дата: 10.12.08 13:08
Оценка:
Здравствуйте, Anpek, Вы писали:

A>Здравствуйте, fmiracle, Вы писали:


A>А нельзя в get ввести булевский аргументик "создавать если нет?" ?


а ещё можно завести enum ForceCreate { create };
И иметь get со вторым параметром типа ForceCreate....
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: get_or_create как правильно назвать
От: Undying Россия  
Дата: 11.12.08 11:58
Оценка:
Здравствуйте, Andrei F., Вы писали:

K>>чем бы заменить слишком длинное имя item_get_or_create?


AF>ensure, force_get

AF>И с чем несогласны несогласные?

force_get совсем непонятно. "Принудительно получить" ни как не ассоциируется с тем, что элемент будет создан в случае отсутствия.

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

get_or_create же очень точное название, из которого сразу понятно, что произойдет при вызове.
Re[3]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 11.12.08 12:18
Оценка:
Здравствуйте, Undying, Вы писали:

U>ensure_get, т.е. "гарантированно получить" это несколько лучше, из такого названия можно понять, что элемент будет получен в любом случае, но непонятно будет ли получаемый элемент добавлен в коллекцию в случае его отсутствия или нет.


Не вижу смысла в таком странном поведении.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 12.12.08 17:35
Оценка:
Здравствуйте, Undying, Вы писали:

U>ensure_get,


Оригинально было просто "ensure", что встречается довольно часто.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[5]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 12.12.08 17:35
Оценка:
Здравствуйте, Undying, Вы писали:

AF>>Не вижу смысла в таком странном поведении.


U>Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу,


Что это за стандарт? Зависит только от библиотеки.

U> но часто бывает, что от Dictionary требуется безопасное поведение, т.е. нужно, чтобы при обращении по несуществующему ключу возвращался null, для чего пишется метод get_or_default(T key).


Нет, по-нормальному делается TryGetItem, которая или получить результат или узнать, что результата нет. get_or_default не даёт информации о результате и, в большинстве случаев, для словаря, бесполезна.

U>…Соответственно при использовании ensure_get непонятно скрывается ли под ним get_or_create или get_or_default.


Обычно, методы с префиком "ensure" смотрят: выполняется ли какое-либо условие, и если не выполняется, делают так, что бы условие выполнялось. Если условием является наличие элемента в контейнере, то что будет делать метод ensure, ИМХО, очевидно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re: get_or_create как правильно назвать
От: SleepyDrago Украина  
Дата: 15.12.08 11:22
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Привет всем.

K>Решил навести порядок в именах, не могу подобрать хорошеее и правильное название для функции.

K>Имеем:

K>
K>Item* item_add(keys...); // создает новый элемент в контейнере в соотвестивии с ключом (или ключами) keys
K>Item* item_get(keys...); // возвращает элемент по keys или NULL
K>Item* item_get_or_create(keys...); // возвращает существующий элемент если он есть или создает новый
K>


K>чем бы заменить слишком длинное имя item_get_or_create?


Имхо посмотрите на это с такой стороны. Сейчас этим item_get_or_create пользуются те кому наплевать что они только что изменили коллекцию. Сделаем шаг в будущее и добавим пул рабочих потоков и опа это крешбаг.
Имеет смысл убрать этот метод а для простоты отлова всех кто им пользуется лучше завести вспомогательную функцию и название ее сделать еще длиннее — чтобы сразу было видно что тут проблема с порядком инициализации.
Re[7]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 12:03
Оценка:
Здравствуйте, Undying, Вы писали:

U>>> но часто бывает, что от Dictionary требуется безопасное поведение, т.е. нужно, чтобы при обращении по несуществующему ключу возвращался null, для чего пишется метод get_or_default(T key).

_FR>>Нет, по-нормальному делается TryGetItem, которая или получить результат или узнать, что результата нет. get_or_default не даёт информации о результате и, в большинстве случаев, для словаря, бесполезна.
U>На практике логике выполнения программы в 99% случаях безразлично равно ли значение по ключу null или ключа в словаре нет вообще. Соответственно использование функции DictionaryHlp.GetValueOrDefault (или dictionary.FindObject на extension) логике программы никак не мешает, зато и лаконичнее и безопаснее в использовании.

Ну значит у меня "неправильные" программы — TryGetValue постоянно пользуюсь именно потому что нет (и не надо) в стандартной библиотеке Ensure.

_FR>>Обычно, методы с префиком "ensure" смотрят: выполняется ли какое-либо условие, и если не выполняется, делают так, что бы условие выполнялось. Если условием является наличие элемента в контейнере, то что будет делать метод ensure, ИМХО, очевидно.


U>И как понять, что ensure проверяет именно наличие элемента в коллекции, а не что-то другое? Ладно бы еще метод ensure_get назывался, там хоть какой-то намек есть в названии.


Я думаю, что метод
TItem EnsureItem<TKey, IItem>(this IDictionary<TKey, IItem> source, TKey key, Func<TKey, TItem> creator);

никого бы не смутил непониманием логики своей работы Точно так же, если коллекция сама знает как создать элемент, метод
TItem EnsureItem(TKey key);

в интерфейсе коллекции выглядел бы осознанно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 12:11
Оценка:
Здравствуйте, _FRED_, Вы писали:

U>>Например, для Dictionary стандартное поведение это бросить исключение при обращении по несуществующему ключу,


_FR>Что это за стандарт? Зависит только от библиотеки.


Широко-распространенные бибилиотеки де-факто и задают стандарт.
За примером далеко ходить не надо: Hashtable из .Net Framework-а.
Re[8]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 12:22
Оценка:
Здравствуйте, _FRED_, Вы писали:

L>>Широко-распространенные бибилиотеки де-факто и задают стандарт.

L>>За примером далеко ходить не надо: Hashtable из .Net Framework-а.

_FR>Не очень удачный пример неудачно спроектированного контейнера. Чего с него пример брать? Взгляни на более продуманный IDictionary<,>.


С чего ты взял, что он более продуманный? Он просто другой.
Re[2]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:13
Оценка:
Здравствуйте, Lloyd, Вы писали:

K>>чем бы заменить слишком длинное имя item_get_or_create?


L>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.

L>Так что бей на два метода и не ошибешься.

Наоборот, "умные дядьки" делают то, что народу нужно. Для примера: умные дидьки из Оракла сделали ALTER_OR_CREATE (точно не знаю, как зовётся, но смысл, думаю, понятен), а другие дядьки из MSSQL, которых мы не будем никак характеризовать, "жмутся". Разработчикам БД это ой как жизнь портит.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:27
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А в "наследство" нам достались такие вот хитрости:


Это разве хитрости? Один знакомый "фокусник" любил писать вот в таком духе:
string path = CurDir.Files[name]; // здесь очень весело - если файла с таким именем нет в коллекции, то он не только в нее добавляется, но еще и создается на диске ;)

Очень свежее решение. Нетривиальное
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[2]: get_or_create как правильно назвать
От: Andrei F.  
Дата: 15.12.08 13:31
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.


Для облегчения жизни себе или пользователю твоей библиотеки?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[11]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 13:36
Оценка:
Здравствуйте, Andrei F., Вы писали:

_FR>>А в "наследство" нам достались такие вот хитрости:

AF>Это разве хитрости? Один знакомый "фокусник" любил писать вот в таком духе:
AF>string path = CurDir.Files[name]; // здесь очень весело - если файла с таким именем нет в коллекции, то он не только в нее добавляется, но еще и создается на диске ;)

AF>Очень свежее решение. Нетривиальное

Да уж Операция-то, конечно, сама по себе нормальная, но называться ждолжна не "индексер", а Ensure…, кстати о теме топика
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[10]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:20
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


Ссылочку на авторство этого высказывания дашь?
Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.

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


О каких сложных идиомах в случае Dictionary идет речь?

_FR>А в "наследство" нам достались такие вот хитрости:

_FR>
_FR>Hashtable map = …;
_FR>var count1 = map.Count;
_FR>var item = map[key];
_FR>map[key] = item;
_FR>var count2 = map.Count; // count2 может отличаться от count1.
_FR>


Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.

_FR>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.
Re[3]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:22
Оценка:
Здравствуйте, Andrei F., Вы писали:

L>>Умные дядьки рекомендуют для облегчения жизни явно разделять функции запрашивающие состояние и меняющие его.


AF>Для облегчения жизни себе или пользователю твоей библиотеки?


Для облегчения жизни кодо-писателю.
Re[11]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 14:30
Оценка:
Здравствуйте, Lloyd, Вы писали:

_FR>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


L>Ссылочку на авторство этого высказывания дашь?


Какого именно?

L>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.


А так, что из плохого дизайна хорошую реализацию сложно сделать.

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


L>О каких сложных идиомах в случае Dictionary идет речь?


Об использовании TryGetItem

_FR>>А в "наследство" нам достались такие вот хитрости:


L>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.


Я определён: "хитрости" могли бы "отпугнуть индусов".

_FR>>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


L>Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.


Это к лову о том, почему я назвал Hashtable неудачно спроектированным контейнером
Автор: _FRED_
Дата: 15.12.08
. Будь он удачно спроектирован, зачем, с появлением дженериков надо было бы менять такие важные части его как работа в многопоточной среде и прочее?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[12]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 14:42
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.


L>>Ссылочку на авторство этого высказывания дашь?


_FR>Какого именно?


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

L>>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.


_FR>А так, что из плохого дизайна хорошую реализацию сложно сделать.


Гм. Мы вроде как обсуждали поведение индексера. Что могло помешать им бросить exception в нем?

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


L>>О каких сложных идиомах в случае Dictionary идет речь?


_FR>Об использовании TryGetItem


Ну если ты считаешь это сложной идиомой, пусть будет так.

_FR>>>А в "наследство" нам достались такие вот хитрости:


L>>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.


_FR>Я определён: "хитрости" могли бы "отпугнуть индусов".


Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".
Я так и не понял, напугали их или нет в итоге?

_FR>>>У меня сейчас нет под рукой Framework Design Guidelines, но, думаю, не сильно ошибусь, если предположу, что в ней советуют вместо ArrayList использовать List<object>, а вместо Hashtable Dictionary<object, object> (если более точные типы указать нельзя).


L>>Понятно, что List, а не ArrayList. Только это аргументом за то или иное поведение индексера ну никак не является.


_FR>Это к лову о том, почему я назвал Hashtable неудачно спроектированным контейнером
Автор: _FRED_
Дата: 15.12.08
. Будь он удачно спроектирован, зачем, с появлением дженериков надо было бы менять такие важные части его как работа в многопоточной среде и прочее?


Да блин, как это к инексеру-то относится?
Re[13]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 15.12.08 15:05
Оценка:
Здравствуйте, Lloyd, Вы писали:

_FR>>>>Ты реализацию Hashtable.get_Item видел? c Thread.Sleep внутри? А не думал, почему в System.Collections.Generic не сделали никакой поддержки многопоточности вообще? Hashtable пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться.

L>>>Ссылочку на авторство этого высказывания дашь?
_FR>>Какого именно?
L>На то, что разработчики "пытались сделать суперпростой и суперфункциональной одновременно, что бы любой дурак понял, как ей пользоваться".

Это мой собственный вывод из того, что я вижу.

L>>>Да, кстати, как связаны дизайн контейнера и его реализация? Как-то не могу понять.

_FR>>А так, что из плохого дизайна хорошую реализацию сложно сделать.
L>Гм. Мы вроде как обсуждали поведение индексера. Что могло помешать им бросить exception в нем?

Этого я не знаю. Если интересно, могу выложить свои догадки.

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

L>>>О каких сложных идиомах в случае Dictionary идет речь?
_FR>>Об использовании TryGetItem
L>Ну если ты считаешь это сложной идиомой, пусть будет так.

Я видел с десяток парней с профильным образованием и опытом в несколько лет, которые педалили Hashtable несколько лет, потом пересели на дженерики, заметили, что те выбрасывают исключение и стали педалить так
if(!map.ContainsKey(key)) {
  Smth smth = new Smth();
  map.Add(key, smth);
}//if
return map[key];

Использовать TryGetValue отчего-то даже после намёка на это не получалось по-первой.

_FR>>>>А в "наследство" нам достались такие вот хитрости:

L>>>Ну вот, то "не отпугнуть индусов", то "хитрости". Ты уж как-нибудь определись.
_FR>>Я определён: "хитрости" могли бы "отпугнуть индусов".
L>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".
L>Я так и не понял, напугали их или нет в итоге?

Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[14]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 15:15
Оценка:
Здравствуйте, _FRED_, Вы писали:

L>>Как-то не согласуется. С одной стороны ты говоришь, что проектировали для индусов. С другой — что есть "хитрости" которые могли бы "отпугнуть индусов".

L>>Я так и не понял, напугали их или нет в итоге?

_FR>Я нигде не говорил, что "хитрости" "могли бы "отпугнуть индусов"." Я только сказал что "хитрости" есть, которые невооружённым индусским взглядом не заметишь.


А это наверное злой хакер написал, укравший твой парол? Вот ведь подлец!

Я определён: "хитрости" могли бы "отпугнуть индусов".

Re[18]: get_or_create как правильно назвать
От: Lloyd Россия  
Дата: 15.12.08 16:31
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>но опять, же, ИМХО, TryGetValue выглядит приятнее.


Ну вот, можешь же. А то начал какую-то тягомотину про sleep-ы, да про коллег.
Re: get_or_create как правильно назвать
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.12.08 05:10
Оценка:
Здравствуйте, Kluev, Вы писали:
K>чем бы заменить слишком длинное имя item_get_or_create?
0. Конвенция именования
1. Если ситуация отсутствия запрошенного ключа в коллекции — редкая, то лучше ничего в нее не добавлять, а в хелперном методе возвращать один и тот же дефолтный объект (Re[17]: get_or_create как правильно назвать
Автор: _FRED_
Дата: 15.12.08
). При этом метод должен называться не get_or_create_item , а get_item_or_default.
2. Если всё как раз наоборот, и в большинстве случаев объекта всё еще нету, то лучше сосредоточиться на том, что объект создается.
То есть метод называется create_item, а в комментах к нему написано, что в случае наличия готового айтема он возвращает его, а не новый.
3. item_get_or_create — не слишком хороший выбор.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 16.12.08 08:04
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_FR>>Как альтернатива TryGetValue, можно было бы либо

_FR>>class Hashtable : …
_FR>>{
_FR>>  public static readonly object NotFound = new object();

AVK>Нафик нафик. Никак вон с DBNull размахаться не получается

ИМХО, лучше чем null. И не хуже, чем -1 в IList<T>.IndexOf и иже с ним. Но, естественно, далеко не образец.

_FR>>struct Option
_FR>>{
_FR>>  public bool HasValue { get; }
_FR>>  public object Value { get; }
_FR>>}


AVK>Этот вариант уже вполне нормален, но в большинстве случаев синтаксически немножко более избыточен, чем TryGetValue. Оба этих варианта легко переходят один к другому при помощи простеньких статических хелперов.


Плохо в обоих вариантах то, что надо либо запрещать добавлять в словарь Hashtable.NotFound/Option, либо опять же будет неоднозначность.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[21]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 16.12.08 12:16
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_FR>>ИМХО, лучше чем null.

AVK>Вот даже и не знаю, какое из двух кривых решений лучше.
_FR>> И не хуже, чем -1 в IList<T>.IndexOf
AVK>Хуже. Потому что -1 того же типа, в отличие от.

А почему тот же тип — лучше? Получаются примерно те же грабли, что и тут
Автор: _FRED_
Дата: 15.12.08
.
Как-то я видел фреймворк для работы с БД, в котором null-значения передавались так:
class CustomConverter
{
  public const int Int32Null = Int32.MinValue;
  // … И так далее в том же духе для остальных типов
  
  public static bool IsNull(int value) { /* */ }
  
  public static bool IsNull(object value) { /* образно говоря, switch/if по типам */ }
}

С одной стороны, да, хорошо: специальные значения не портят "чистоту" при работе с "нормальными" значениями. А в итоге те же описанные выше грабли — надо не забывать повсюду ставить проверки и при работе со стандартными, собственно, типами (int, double, decimal) пользоваться "услугами" класса CustomConverter, в котором сосредоточена логика проверки значений, обращений к которому получается так много, что кажется ради него вся работа и задумана.

С DBNull же Value (как со специальным значение, которое нельзя ни с чем перепутать) — как только хочешь что-то посчитать, делаешь приведение типа и получаешь по рукам, если не проверил данные.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re[22]: get_or_create как правильно назвать
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.12.08 18:55
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А почему тот же тип — лучше?


Более очевидный код получается.

_FR>Получаются примерно те же грабли, что и тут
Автор: _FRED_
Дата: 15.12.08
.


Я, уж извини, не хочу искать в этой простыне грабли. Можно поконкретнее?


_FR>Как-то я видел фреймворк для работы с БД, в котором null-значения передавались так:


Неверная аналогия. Индекс равным -1 быть не может в принципе, в отличие от.
... << RSDN@Home 1.2.0 alpha 4 rev. 1120 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[23]: get_or_create как правильно назвать
От: _FRED_ Черногория
Дата: 17.12.08 06:47
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_FR>>А почему тот же тип — лучше?

AVK>Более очевидный код получается.

Когда Hashtable возвращает null, и на основании этого кажется, что словарь не нашёл значение, код тоже кажется очевидным. Да?

_FR>>Получаются примерно те же грабли, что и тут
Автор: _FRED_
Дата: 15.12.08
.

AVK>Я, уж извини, не хочу искать в этой простыне грабли. Можно поконкретнее?

В том, что можно не сделать проверку и узнать об этом неизвестно когда, если вообще узнать.

_FR>>Как-то я видел фреймворк для работы с БД, в котором null-значения передавались так:

AVK>Неверная аналогия. Индекс равным -1 быть не может в принципе, в отличие от.

Не может, но во избежании ошибок повсюду этот индекс приходится проверять, даже там, где, я уверен, ошибки быть не может. Потому что если всё же ошибка в этом месте случится, то отыскать, где именно произошли грабли станет чертовски трудно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Help will always be given at Hogwarts to those who ask for it.
Re: get_or_create как правильно назвать
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 25.12.08 10:42
Оценка:
K>Привет всем.
K>Решил навести порядок в именах, не могу подобрать хорошеее и правильное название для функции.

K>Имеем:

K>
K>Item* item_add(keys...); // создает новый элемент в контейнере в соотвестивии с ключом (или ключами) keys
K>Item* item_get(keys...); // возвращает элемент по keys или NULL
K>Item* item_get_or_create(keys...); // возвращает существующий элемент если он есть или создает новый
K>


K>чем бы заменить слишком длинное имя item_get_or_create?


Получение и правку всегда лучше разносить. Хотя бы из-за разного отношения к транзакциям и блокировкам.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.