Из эмпирического тестирования кажется, что max()
и min()
в списке вернут первое в списке, которое соответствует max()
/ min()
в случае связи:
>>> test = [(1, "a"), (1, "b"), (2, "c"), (2, "d")]
>>> max(test, key=lambda x: x[0])
(2, 'c')
>>> test = [(1, "a"), (1, "b"), (2, "d"), (2, "c")]
>>> max(test, key=lambda x: x[0])
(2, 'd')
>>> min(test, key=lambda x: x[0])
(1, 'a')
>>> test = [(1, "b"), (1, "a"), (2, "d"), (2, "c")]
>>> min(test, key=lambda x: x[0])
(1, 'b')
И Отличное слежение Джереми подтверждает, что это действительно так.
Добавьте его в модель
has_one :sender, :class_name => "User"
has_one :recipient, :class_name => "User"
И вы можете вызвать @ message.sender
и @ message.recipient
и обе ссылки на пользовательскую модель.
Вместо user: references
в команде создания вам понадобится sender: references
и recipient: references
На самом деле больше нет такого понятия, как «ядро». Раньше был стандартный дистрибутив Perl, но у многих людей нет стандартного дистрибутива Perl. Дистрибутивы операционной системы изменяют его, добавляя или удаляя модули, меняя модули и т. д. Нельзя полагаться на то, что стандартное распределение действительно является стандартным. Некоторые дистрибутивы Linux даже не включают документацию Perl как часть базовой установки Perl.
Вы говорите, что вы не можете использовать Module:: CoreList , потому что он не является ядром, но если вы можете создать файлы, вы можете установить модуль. Можно даже притвориться, что написал сам.
-121--1042492-В J большинство примитивов (а.к. функции) являются монадическими (один аргумент) или диадическими (два аргумента, один слева, один справа). Но поправка примитив занимает 3 (я думаю, что это единственный, кроме иностранцев). Понятно, что это займет 3, но это просто выглядит... сначала неправильно.
vector =: i. 10 NB. Vector will be 0 1 2 3 4 5 6 7 8 9
(10) (0) } vector NB. Will yield 10 1 2 3 4 5 6 7 8 9
в j , иностранные (!:
) различные функции, свернутые вместе. Левый аргумент - это категория, где, как правило, часто (но не всегда) инкрементные значения для разных ... вещей. Например:
2!:55 NB. Close console 9!:10 NB. Set print precision 6!:0 NB. Actual time 6!:2 NB. Execution time 4!:3 NB. Loaded scripts
, конечно, умная вещь - обернуть их, но некоторые вы просто обходите в память. Кстати, все это, приходят, чтобы подумать об этом, триадично, с 2 аргументами справа и один налево. Ни один из вышеперечисленных не будет работать, если вы не дадите им окончательный допустимый аргумент.
В awk массивы начинаются с индекса 1, что сбивает с толку наименее.
В Питоне, по крайней мере для меня, это было очень сильно! Первый раз, когда я увидел это:
>>> "ja " * 5
'ja ja ja ja ja '
Ты можешь умножать строки! WTF???
PS: Я думаю, это потому, что x * n
означает: n раз x
так что 5 раз "ja "
это "ja ""ja ""ja ""ja "
и потому что вы можете соединять строки вот так:
>>> "ja ""ja ""ja ""ja ""ja "
'ja ja ja ja ja '
Что два кода имеют один и тот же результат (и, возможно, просто один и тот же)
.In C#, следующий код генерирует ошибку компилятора "Cannot convert from method group to Delegate" (Невозможно преобразовать из группы методов в Delegate). И хотя логика, лежащая в основе ошибки, разумна, она все же кажется мне странной.
control.BeginInvoke(delegate { DoSomething(); });
имплантат variables\constants и мутирующие константы в рубине
.В Java существует некоторая несогласованность в том, как Strings обрабатывают оператор == в зависимости от того, как он был построен.
String a = "Hello";
String b = "Hello";
System.out.println(a == b ); // prints true.
String c = new String("Hello");
String d = new String("Hello");
System.out.println(c == d ); // prints false
Исходный файл Java может заканчиваться символом \ u001a
(control-Z).
Вот один о питоне:
>>> print 07
7
>>> print 08
File "<stdin>", line 1
print 08
^
SyntaxError: invalid token
Разве это не красота?
Особенно невнимательно, когда вы думаете о том, как люди пишут даты, у которых есть следующий эффект:
datetime.date(2010,02,07) # ok
datetime.date(2010,02,08) # error!
(причина в том, что 0x
интерпретируется как восьмеричное, поэтому print 010
выводит 8
!)
Ну, первое, что пришло мне в голову, было «нет», мой мозг сделал то же самое, когда я впервые наткнулся на это!
В схеме нет зарезервированных идентификаторов . Итак, следующее выражение оценивается как 1:
((lambda (lambda) lambda) (let ((let 1)) let))
Обратите внимание, что существует ограничение на определения в пределах данной области: никакое определение не может переопределить идентификатор, используемый для определения идентификаторов в этой области, поэтому следующее является синтаксической ошибкой:
(begin (define define 1) define)
Слабый набор текста, в общем.
C:
printf("%c\n", 'a' + 3);
PHP:
echo 5 + "3";
И слишком много других языков.
Статические методы преобразования базы класса Integer Java. :P Похоже, что очень немногие языки имеют встроенную функциональность.
]Modula-2 не имеет []elseif[
] или []else if[
]; он имеет []elsif[
][
Вот одна, которая мне показалась странной:
В языке Си/Си++ вы можете иметь столько точек с запятой, сколько захотите, по крайней мере, в MS C++:
int main(void)
{
cout<<"Hello World";;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;
return 0;;;;;;;;;;;;;;;;;;;;;;;
}
COMEFROM - самая странная и, наверное, самая бесполезная языковая особенность, которую я когда-либо видел.
Runner-up был бы тернарным оператором, так как он нарушает правило #1 оптимизации. И он наносит больше вреда, чем решает проблемы. Он приносит больше вреда, потому что делает код менее читабельным.
На самом деле это не совсем языковая возможность, но интересное/очаровательное использование возможностей - это устройство Даффа .
Все автоматически умножает или сингулирует любые имена классов и членов.
Linq-to-Sql, например
.PHP имеет непоследовательную обработку перегрузок, например, переменных и методов. Рассмотрим:
class Foo
{
private $var = 'avalue';
private function doStuff()
{
return "Stuff";
}
public function __get($var)
{
return $this->$var;
}
public function __call($func, array $args = array())
{
return call_user_func_array(array($this, $func), $args);
}
}
$foo = new Foo;
var_dump($foo->var);
var_dump($foo->doStuff());
Работает дамп $var
. Несмотря на то, что $var
является приватным, __get()
вызывается для любого члена, который не существует или недоступен, и возвращает правильное значение. Это не случай для doStuff()
, который не работает с:
Fatal error: Call to private method Foo::doStuff() from context ”.”
Я думаю, что многое из этого работает в языках в стиле Си, но я не уверен.
Передайте здесь документ в качестве аргумента функции:
функция foo($message)
{
эхо-сообщение . "\n";
}
foo(<
Вы можете присвоить переменную в списке аргументов.
foo($message = "Hello");
echo $message;
Это работает, потому что присваивание - это выражение, которое возвращает присваиваемое значение. Это является причиной одной из наиболее распространенных ошибок в C-стиле, выполняющей присваивание вместо сравнения.
В Python изменяемые аргументы функции по умолчанию приводят к неожиданным результатам:
def append(thing, collection=[]):
collection.append(thing)
return collection
print append("foo")
# -> ['foo']
print append("bar")
# -> ['foo', 'bar']
print append("baz", [])
# -> ['baz']
print append("quux")
# -> ['foo', 'bar', 'quux']
Пустой список инициализируется во время определения функции, а не во время вызова, поэтому любые изменения в нем сохраняются во время вызова функции.
MySQL имеет действительно необычные правила чувствительности к регистру: Таблицы чувствительны к регистру, имена столбцов - и значения строк - нет:
mysql> CREATE TEMPORARY TABLE Foo (name varchar(128) NOT NULL);
DESCRIBE foo;
ERROR 1146 (42S02): Table 'foo' doesn't exist
mysql> DESCRIBE Foo;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| name | varchar(128) | NO | | NULL | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.06 sec)
mysql> INSERT INTO Foo (`name`) VALUES ('bar'), ('baz');
Query OK, 2 row affected (0.05 sec)
mysql> SELECT * FROM Foo WHERE name = 'BAR';
+------+
| name |
+------+
| bar |
+------+
1 row in set (0.12 sec)
mysql> SELECT * FROM Foo WHERE name = 'bAr';
+------+
| name |
+------+
| bar |
+------+
1 row in set (0.05 sec)
В C++ я нахожу странным и неприятным, что "виртуальный" MI (множественное наследование) позволяет иерархии классов "алмазной формы" "работать"
A : Базовый класс, например "Объект". Б, В: и то, и другое происходит (практически или нет) от Предмета и D: происходит от B и C
Проблема: "нормальное" наследование приводит к тому, что D - это 2 двусмысленных вида A. "виртуальный" MI обрушивает B's A и C's A на один общий базовый A-объект.
Таким образом, даже если Ваше Колесо - это объект, а Ваше Левое переднее колесо - это Колесо, а Ваш автомобиль наследует четыре вида Колеса, Ваш автомобиль все равно является только одним из видов объектов с виртуальным MI. В противном случае, Ваш автомобиль не является объектом, а является объектом 4-х видов колес.
Это одна из особенностей языка, которая вознаграждает плохой дизайн класса, наказывает писателей компилятора, и оставляет Вас удивляться во время выполнения, где на самом деле находится этот Объект - и если любой виртуальный багаж MI был утерян.
Если вам действительно нужен алмазный шаблон в иерархии класса, это можно сделать с помощью обычного MI и "AProxy", которая делегирует единственную базу A.
A: Базовый класс, например, "Объект". Апроксия: Базовый класс, конструирует с другими A для привязки к В: происходит от А C : происходит от AProxy D : происходит от B и C (переход от A к C AProxy на стадии строительства)
Это требует немного больше работы для тех, кто действительно любит бриллиант MI и оставляет остальных в покое с более уравновешенным набором языковых возможностей.
Не знаю Если это особенность или нет. Для некоторых, да, но для других это может быть раздражающее поведение. Во всяком случае, я думаю, стоит упомянуть.
в Python
, встроенная функция ()
() [) ведет себя немного по-разному между Python 2X и Python 3X.
для PY 2X,
>>> round(0.4)
0.0
>>> round(0.5)
1.0
>>> round(0.51)
1.0
>>> round(1.5)
2.0
для PY 3X,
>>> round(0.4)
0
>>> round(0.5)
0
>>> round(0.51)
1
>>> round(1.5)
2
Я просто не знаком с тем, как Round ()
в PY 3X работает с 0.
в Python:
i = 1
++i
print i
Принты «1». Линия «++ I» оценивает + (+ I) (Python не поддерживает операторы приращения)
Я не знаю, правда ли это по-прежнему, но мы случайно обнаружили, что VS FORTRAN (66 или 77) не поддерживает рекурсию. Рекурсия была случайной, и наш F77 по умолчанию прекрасно ее поддерживал, но когда мы взяли источник в IBM - Whatta Mess.
«динамический» в C #.
Разрушает день для всех, кому приходится работать вместе с жертвой RAD или python, потому что Intellisense, безопасность типов и детерминизм мгновенно умирают при первом использовании ключевого слова dynamic.
Я однажды построил язык с предложением BUT, давным-давно.
На C:
int main() {
int i = 0;
int array[] = {1,2};
return (i[array] + 1 == array[i]);
}
Эта программа вернет 1 (true).
в Java
String("aaa")==String("aaa") //false
//you need to use
String("aaa").equals(String("aaa")) // true
В ColdFusion текстовые значения автоматически преобразуются в различные типы данных для различных целей. Я столкнулся с странной проблемой, когда «00A» и «000» возвращались как равные. Оказалось, что ColdFusion интерпретировал «00A» как время, преобразовывая в какой-то числовой формат времени и преобразовывая его в 0. «000» преобразовывалось в 0. Таким образом, они оба считались эквивалентными. Именно тогда я узнал о функции сравнения строк.
И снова Haskell:
В Haskell вы можете обрабатывать файл произвольного размера, как если бы он был простой String
. Файл будет прочитан только в том случае, если строка действительно используется. Из-за невероятной лени Haskell такая программа будет работать в постоянном пространстве, независимо от размера файла:
main = interact (>>= \x -> if x == '\n' then "\r\n" else [x])
(Эта программа преобразует файл из стандартного ввода в стандартный вывод и заменяет LF на CRLF, взаимодействуют
] функция вводит весь стандартный ввод в функцию и перемещает вывод в стандартный вывод.)
Эта лень может также вызвать проблемы, потому что, если вы закроете дескриптор файла, вы не сможете быть полностью уверены, что ленивый Haskell уже проанализировал все данные от него.
В C,
int x = 1;
int y = x++ + ++x;
printf("%d", y);
Неясно, что будет напечатано, зависит от компилятора. Компилятор может сохранить новое значение x ++ до вычисления ++ x или в конце оператора.