Вместо того, чтобы использовать интервал. TryParse () или Преобразовывают. ToInt32 (), мне нравится иметь статическую целочисленную функцию парсинга, которая возвращает пустой указатель, когда это не может проанализировать. Тогда я могу использовать?? и тернарный оператор вместе, чтобы более ясно гарантировать мое объявление и инициализацию все сделан на одной строке легким для понимания способом.
public static class Parser {
public static int? ParseInt(string s) {
int result;
bool parsed = int.TryParse(s, out result);
if (parsed) return result;
else return null;
}
// ...
}
Этого также хорошо постараться не копировать левую сторону присвоения, но еще лучше стараться не копировать долгие запросы к правой стороне присвоения, такие как база данных звонит в следующий пример. Вместо ужасного, если тогда деревья (с которым я часто сталкиваюсь):
int x = 0;
YourDatabaseResultSet data = new YourDatabaseResultSet();
if (cond1)
if (int.TryParse(x_input, x)){
data = YourDatabaseAccessMethod("my_proc_name", 2, x);
}
else{
x = -1;
// do something to report "Can't Parse"
}
}
else {
x = y;
data = YourDatabaseAccessMethod("my_proc_name",
new SqlParameter("@param1", 2),
new SqlParameter("@param2", x));
}
можно сделать:
int x = cond1 ? (Parser.ParseInt(x_input) ?? -1) : y;
if (x >= 0) data = YourDatabaseAccessMethod("my_proc_name",
new SqlParameter("@param1", 2),
new SqlParameter("@param2", x));
Намного более чистый и легче понять
Я думаю, что ваше замешательство связано с тем, что def не зависит от текущего «я», вы можете думать о нем как о «текущем классе», который имеет свои собственные правила.
Следуя вашим примерам:
class A
# defs here go to A
puts self # => A
class << self
#defs here go to A's eigenclass
end
end
A.class_eval do
#defs here go to A
end
A.instance_eval do
#defs here go to A's eigenclass
end
s = "Hello World"
class << s
#defs here go to s's eigenclass
end
Вот часть главы, в которой говорится о проблеме, и довольно ясно о поведении
class_eval и instance_eval оба устанавливают self для продолжительность блока. Однако они отличаются тем, как они настраивают среду для определения метода. class_eval настраивает вещи так, как если бы вы были в теле определения класса, поэтому определения методов будут определять методы экземпляра. Напротив, вызов instance_eval для класса действует так, как если бы вы работали внутри синглтон-класса self. Поэтому любые методы, которые вы определите, станут методами класса.
Единственное, что я думаю, стоит добавить, это то, что вы можете вызывать instance_eval для любого объекта, не только для классов, и поведение не меняется, но имеет другие последствия.
Некоторое уместное прочтение: