В Ruby, почему не будет 'нечто = верный, если не определено? (нечто)' делают присвоение?

Что продолжается здесь? Каково тонкое различие между двумя формами "если"?

> irb(main):001:0> foo = true unless defined?(foo)
=> nil 
irb(main):002:0> unless defined?(fooo) ; fooo = false ; end
=> false 

спасибо

14
задан FMc 20 February 2010 в 15:52
поделиться

7 ответов

По-видимому, ruby ​​создает локальную переменную во время синтаксического анализа, устанавливая для них значение nil , поэтому она определена и выполняется независимо от того, выполняется ли код или нет.

Когда код оценивается в вашей первой строке, он не выполняет часть присваивания, поскольку для foo установлено значение nil . Во второй строке, поскольку fooo еще не проанализирован, defined? возвращает nil , позволяя коду внутри блока выполнить и назначить fooo .

В качестве примера вы можете попробовать следующее:

if false  
  foo = 43  
end  
defined? foo  
=> "local-variable"

Это взято из сообщения форума на ruby-forum.

16
ответ дан 1 December 2019 в 09:01
поделиться
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"

По-видимому, определено? () возвращает истину, так как он уже видел полосу (в начале строки), даже если вы все еще находитесь в процесс его определения.

2
ответ дан 1 December 2019 в 09:01
поделиться

Давайте начнем с чего-то более простого:

# 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 - возвращаемое значение нашего блока.

12
ответ дан 1 December 2019 в 09:01
поделиться

в первом случае вы вызываете 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
1
ответ дан 1 December 2019 в 09:01
поделиться

Ну ... Одна форма - это блок, а другая - нет. Вторая часть, блок, возвращает последний вычисленный оператор. Первый .. Хм .. Я не знаю, что он делает.

-1
ответ дан 1 December 2019 в 09:01
поделиться

Я использую 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
ответ дан 1 December 2019 в 09:01
поделиться

Август, все выглядит нормально в 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"
1
ответ дан 1 December 2019 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: