Посмотрите на CGI в Википедии. CGI является протоколом между веб-сервером и внешней программой или скриптом, который обрабатывает ввод и генерирует вывод, который отправляется в браузер.
CGI - это просто способ веб-сервер и программа для общения, не более того, не меньше. Здесь сервер управляет сетевым соединением и протоколом HTTP, и программа обрабатывает ввод и генерирует вывод, который отправляется в браузер. CGI-скрипт может быть в основном любой программой, которая может быть выполнена веб-сервером и следует протоколу CGI. Таким образом, программа CGI может быть реализована, например, на C. Однако это очень редко, так как C не очень хорошо подходит для задачи.
/cgi-bin/*.cgi
- это просто путь, их сценарий CGI. Веб-сервер обычно настроен по умолчанию для получения CGI-скриптов с этого пути.
скрипт CGI может быть реализован также в PHP, но все PHP-программы не являются скриптами CGI. Если веб-сервер имеет встроенный PHP-интерпретатор (например, mod_php в Apache), тогда фаза CGI пропускается более эффективным прямым протоколом между веб-сервером и интерпретатором.
Независимо от того, был ли вы реализован сценарий CGI или нет, это зависит от как ваш скрипт выполняется веб-сервером.
ОБНОВЛЕНИЕ. Поскольку этот ответ, похоже, получил некоторый интерес в последнее время, я хотел бы указать, что обсуждение g0 на трекер-проблеме Ruby устраняет обсуждаемую здесь функцию, а именно, запретить определение методов внутри тела метода .
Нет, Ruby не имеет вложенных методов.
Вы можете сделать что-то вроде этого:
class Test1
def meth1
def meth2
puts "Yay"
end
meth2
end
end
Test1.new.meth1
Но то есть не вложенный метод. Повторяю: Ruby не имеет вложенных методов .
Что это такое, это определение динамического метода. Когда вы запустите meth1
, тело meth1
будет выполнено. Тело просто определяет метод с именем meth2
, поэтому после запуска meth1
один раз вы можете вызвать meth2
.
Но где определено meth2
? Ну, очевидно, не определяется как вложенный метод, так как не являются вложенными методами в Ruby. Он определен как метод экземпляра Test1
:
Test1.new.meth2
# Yay
Кроме того, он будет, очевидно, переопределяться каждый раз при запуске meth1
:
Test1.new.meth1
# Yay
Test1.new.meth1.
# test1.rb:3: warning: method redefined; discarding old meth2
# test1.rb:3: warning: previous definition of meth2 was here
# Yay
Короче: no , Ruby не поддерживает вложенные методы.
Обратите также внимание на то, что в Ruby тела методов не могут быть закрытыми, только блокирующие тела могут. Это в значительной степени устраняет основной вариант использования вложенных методов, поскольку даже , если Ruby поддерживает вложенные методы, вы не могли использовать переменные внешнего метода во вложенном методе.
ОБНОВЛЕНИЕ ПРОДОЛЖЕНИЕ: на этапе later , этот синтаксис может быть повторно использован для добавления вложенных методов в Ruby, которые будут вести себя так, как я описал: они будут привязаны к их содержащему методу, т.е. невидимыми и недоступными вне тела их тела. И, возможно, у них будет доступ к лексическому охвату их содержательного метода. Однако, если вы прочитаете обсуждение, которое я связал выше, вы можете заметить, что matz сильно зависит от вложенных методов (но все же для удаления вложенных определений методов).
: - D
Ruby имеет вложенные методы, только они не делают того, что вы ожидаете от них
1.9.3p484 :001 > def kme; 'kme'; def foo; 'foo'; end; end
=> nil
1.9.3p484 :003 > self.methods.include? :kme
=> true
1.9.3p484 :004 > self.methods.include? :foo
=> false
1.9.3p484 :005 > kme
=> nil
1.9.3p484 :006 > self.methods.include? :foo
=> true
1.9.3p484 :007 > foo
=> "foo"
Нет, нет, у Ruby есть вложенные методы. Проверьте это:
def outer_method(arg)
outer_variable = "y"
inner_method = lambda {
puts arg
puts outer_variable
}
inner_method[]
end
outer_method "x" # prints "x", "y"
Вы можете сделать что-то вроде этого
module Methods
define_method :outer do
outer_var = 1
define_method :inner do
puts "defining inner"
inner_var = outer_var +1
end
outer_var
end
extend self
end
Methods.outer
#=> defining inner
#=> 1
Methods.inner
#=> 2
Это полезно, когда вы делаете такие вещи, как запись DSL, которые требуют совместного использования области между методами. Но в противном случае вам намного лучше делать что-либо еще, потому что, как говорят другие, inner
переопределяется всякий раз, когда вызывается outer
. Если вы хотите этого поведения, а иногда можете, это хороший способ его получить.
На самом деле это возможно. Вы можете использовать procs / lambda для этого.
def test(value)
inner = ->() {
value * value
}
inner.call()
end
Путь Ruby заключается в том, чтобы подделать его с запутанными хаками, которые заставят некоторых пользователей задаться вопросом: «Как в fuck это даже работает?», в то время как менее любопытный просто запоминает синтаксис, необходимый для использования этой вещи. Если вы когда-либо использовали Rake или Rails, вы видели такие вещи.
Вот такой хак:
def mlet(name,func)
my_class = (Class.new do
def initialize(name,func)
@name=name
@func=func
end
def method_missing(methname, *args)
puts "method_missing called on #{methname}"
if methname == @name
puts "Calling function #{@func}"
@func.call(*args)
else
raise NoMethodError.new "Undefined method `#{methname}' in mlet"
end
end
end)
yield my_class.new(name,func)
end
Что это значит, который создает класс и передает его блоку. Класс использует method_missing
, чтобы притворяться, что у него есть метод с именем, которое вы выбрали. Он «реализует» метод, вызывая лямбда, которую вы должны предоставить. Назвав объект однобуквенным именем, вы можете свести к минимуму количество лишнего ввода, которое оно требует (что то же самое, что Rails делает в schema.rb
). mlet
назван в честь формы Common Lisp flet
, за исключением случаев, когда f
обозначает «функцию», m
обозначает «метод».
Вы используете его следующим образом:
def outer
mlet :inner, ->(x) { x*2 } do |c|
c.inner 12
end
end
Можно создать аналогичное приспособление, которое позволяет определять множество внутренних функций без дополнительного вложения, но для этого требуется еще более уродливый взлом такого рода, который вы можете найти в реализации Rake или Rspec. Выяснение того, как работает Rspec let!
, даст вам долгий путь к созданию такой ужасной мерзости.