Что продолжается здесь? Каково тонкое различие между двумя формами "если"?
> irb(main):001:0> foo = true unless defined?(foo)
=> nil
irb(main):002:0> unless defined?(fooo) ; fooo = false ; end
=> false
спасибо
По-видимому, ruby создает локальную переменную во время синтаксического анализа, устанавливая для них значение nil
, поэтому она определена и выполняется независимо от того, выполняется ли код или нет.
Когда код оценивается в вашей первой строке, он не выполняет часть присваивания, поскольку для foo
установлено значение nil
. Во второй строке, поскольку fooo
еще не проанализирован, defined?
возвращает nil
, позволяя коду внутри блока выполнить и назначить fooo
.
В качестве примера вы можете попробовать следующее:
if false
foo = 43
end
defined? foo
=> "local-variable"
irb(main)> foo = true unless defined?(Integer)
=> nil
irb(main)> foo = true unless defined?(thisIsUndefined)
=> true
Ваш первый блок возвращает nil
, потому что способ его записи оставляет 2 варианта:
foo
не определено - -> assign true foo
определено -> ничего не делать Здесь foo должно быть определено при вычислении строки. Таким образом, ничего не происходит и возвращается nil
.
irb(main)> unless defined?(Integer) ; fooo = false ; end
=> nil
irb(main)> unless defined?(thisIsUndefined) ; fooo = false ; end
=> false
Ваш второй блок работает так же, как и ваш первый.Если fooo
не определен, блок вводится и fooo
устанавливается на false
. Результатом последней строки блока является возвращаемое значение блока, поэтому вы видите false
. Если fooo
действительно существует, то блок пропускается и ничего не происходит, поэтому возвращать нечего, поэтому nil
.
Основываясь на вашем коде, я бы сказал, что foo
был определен при запуске этого кода, а fooo
- нет (показанный тестовый код был сгенерирован в Ruby 1.8.6). Если вы не определили ни один из них перед запуском этого кода, то у вас может быть что-то под названием foo
, которое определено по умолчанию (определено ли ? (Foo)
для проверки). Попробуйте использовать другое имя и посмотрите, получите ли вы те же результаты.
Изменить:
irb(main)> defined?(bar)
=> nil
irb(main)> bar = true unless defined?(bar)
=> nil
irb(main)> defined?(bar)
=> "local-variable"
По-видимому, определено? ()
возвращает истину, так как он уже видел полосу
(в начале строки), даже если вы все еще находитесь в процесс его определения.
Давайте начнем с чего-то более простого:
# z is not yet defined
irb(main):001:0> defined?(z)
=> nil
# Even though the assignment won't execute,
# the mere presence of the assignment statement
# causes z to come to life.
irb(main):002:0> z = 123 if false
=> nil
irb(main):003:0> defined?(z)
=> "local-variable"
irb(main):004:0> z
=> nil
Теперь мы можем разобраться с вашим первым примером.
foo = true unless defined?(foo)
Определено ли foo
? Пока мы не нажали ENTER в irb
, нет. Однако наличие оператора присваивания заставляет foo
ожить. Это означает, что оператор присваивания не будет выполнен, оставляя foo
существующим, но имеющим nil
в качестве значения. А какое последнее выражение оценивается в строке irb
? Это unless defined?(foo)
, которое оценивается в nil
.
Для получения дополнительной информации о том, как присваивания (даже те, которые не выполняются) приводят к существованию переменных, смотрите обсуждение Двусмысленность переменных/методов.
В вашем втором примере вообще нет ничего загадочного: fooo
не определено, поэтому код в блоке выполняется, устанавливая fooo
в false
. Это присвоение является последним вычисленным выражением, поэтому false
- возвращаемое значение нашего блока.
в первом случае вы вызываете foo
в операторе присваивания. Возможно, это прояснит:
bar = if true
puts bar.class
else
puts "not reached"
end
NilClass
=> nil
baz = if true
puts baz.class
42
else
puts "not reached"
end
NilClass
=> 42
Ну ... Одна форма - это блок, а другая - нет. Вторая часть, блок, возвращает последний вычисленный оператор. Первый .. Хм .. Я не знаю, что он делает.
Я использую Sqlite для хранения данных конфигурации XML и не имел проблем с ней. Я использую поставщик System.Data.Sqlite: http://sqlite.phxsoftware.com/ . Он прочный и имеет хороший форум поддержки. Он также включает провайдера LINQ. Он также интегрируется с VS 2008, чтобы можно было использовать проводник сервера для запроса таблиц. Примеры и документация также показывают, как использовать параметризованные команды и транзакции для повышения производительности.
Кандидат на выпуск LinqPad теперь поддерживает Sqlite: http://www.linqpad.net/Beta.aspx .
Sqlite хранит все в одном файле, который можно резервировать, как и любой другой двоичный файл.
Sqlite поддерживает только блокировку на уровне файлов, но не должен создавать проблемы с производительностью, так как это не похоже на то, что у вас будет большое количество одновременных транзакций.
Юникод не должен быть проблемой. Эта ссылка на форуме обращается к области, где кто-то пытался прочитать символы Юникода с несовместимой утилитой http://sqlite.phxsoftware.com/forums/t/954.aspx .
На этом сайте показано, как выполнять сравнение UTF8 без учета регистра с помощью System.Data.Sqlite с помощью пользовательского коллятора, с русскими символами в качестве примера: http://www.codeproject.com/KB/database/SQLiteUTF8CIComparison.aspx .
-121--4746177-Можно воспользоваться функцией POST, а затем задать для поля формы с именем X-HTTP-Method-Override значение DELETE.
См. вопрос SO # 467535 для конкретных примеров:
Возможно ли реализовать X-HTTP-Method-Override в ASP.NET MVC?
-121--5085948-В Ruby 1,8,7:
foo = true unless defined?(foo)
p foo # => nil
unless defined?(fooo); fooo = true; end
p foo # => nil
У меня нет объяснения поведения, которое вы видите.
Август, все выглядит нормально в 1.8.7:
$ irb
irb(main):001:0> unless defined?(fooo); fooo = true; end
=> true
irb(main):002:0> fooo
=> true
irb(main):003:0> `ruby --version`
=> "ruby 1.8.7 (2008-06-20 patchlevel 22) [i486-linux]\n"