Действительно ли Ruby является интерпретируемым языком, если все его реализации скомпилированы в байт-код?

StackOverflow https://stackoverflow.com/questions/717490

Вопрос

В выбранном ответе на этот вопрос о Blue Ruby, Чак говорит:

Все текущие реализации Ruby составлены в Bytecode.Вопреки утверждениям САП, поскольку Ruby 1.9, сама МРТ включает в себя компилятор байткода, хотя возможность для сохранения скомпилированного байткода на диск исчез где-то в процессе объединения виртуальной машины YARV.JRuby компилируется в Java.class файлы.У меня нет много подробностей на MagLev, но, кажется, безопасно сказать это пойдёт по этой дороге тоже.

Меня смущает эта проблема компиляции/интерпретации в отношении Ruby.

Я узнал, что Ruby — это интерпретируемый язык, и поэтому, когда я сохраняю изменения в своих файлах Ruby, мне не нужно пересобирать проект.

Но если все реализации Ruby теперь скомпилированы, справедливо ли будет говорить, что Ruby является интерпретируемым языком?Или я что-то не понимаю?

Это было полезно?

Решение

Да, Ruby по-прежнему является интерпретируемым языком, или, точнее, Ruby Interpreter (MRI) Матца, о котором люди обычно говорят, когда говорят о Ruby, по-прежнему является интерпретатором.Этап компиляции нужен просто для того, чтобы свести код к чему-то, что выполняется быстрее, чем интерпретация и переинтерпретация одного и того же кода раз за разом.

Другие советы

Сегодня почти каждый язык «компилируется», если считать байт-код компилируемым.Даже Emacs Lisp скомпилирован.Ruby был особым случаем, поскольку до недавнего времени он не было скомпилирован в байт-код.

Я думаю, вы правы, ставя под сомнение полезность характеристики языков как «скомпилированных», а не как «скомпилированных»."интерпретировано". Одно из полезных различий, однако, заключается в том, создает ли язык машинный код (например,ассемблер x86) непосредственно из пользовательского кода.C, C++, многие Lisps и Java с включенным JIT подходят, а Ruby, Python и Perl — нет.

Люди, которые не разбираются в этом лучше, назовут любой язык, в котором есть отдельный этап ручной компиляции, «скомпилированным», а тот, который не требует «интерпретации».

Действительно, тонкий вопрос...Раньше «интерпретируемые» языки анализировались и преобразовывались в промежуточную форму, которая выполнялась быстрее, но «машина», выполняющая их, была красивой программой, специфичной для конкретного языка.Вместо этого «скомпилированные» языки переводились в инструкции машинного кода, поддерживаемые компьютером, на котором он запускался.Раннее различие было очень простым — статическое и статическое.динамический объем.В статически типизированном языке ссылка на переменную в значительной степени могла быть преобразована в адрес памяти за несколько машинных инструкций — вы точно знали, где в вызывающем фрейме ссылается переменная.В динамически типизированных языках вам приходилось искать ссылку (вверх по A-списку или вверх по вызывающему фрейму).С появлением объектно-ориентированного программирования непосредственный характер ссылки расширился до многих других понятий — классов (типов), методов (функций) и даже синтаксической интерпретации (встроенные DSL, такие как регулярное выражение).

На самом деле, начиная с конца 70-х годов, различие заключалось не столько в скомпилированном, сколько в интерпретируемом. языки, но были ли они запущены в скомпилированной или интерпретируемой среде.Например, Паскаль (первый язык высокого уровня, который я изучал) сначала работал в Калифорнийском университете в Беркли на языке Билла Джоя. pxp интерпретатор, а позже и компилятор, который он написал ПКК.Один и тот же язык, доступный как в скомпилированной, так и в интерпретируемой среде.

Некоторые языки более динамичны, чем другие, значение чего-либо — типа, метода, переменной — зависит от среды выполнения.Это означает, что скомпилированный или нет, существует существенный механизм времени выполнения, связанный с выполнением программы.Forth, Smalltalk, NeWs, Lisp — все они были примерами этого.Первоначально для выполнения этих языков требовалось так много механизмов (по сравнению с C или Fortran), что они были естественными для интерпретации.

Еще до появления Java были попытки ускорить выполнение сложных динамических языков с помощью трюков, таких методов, как поточная компиляция, компиляция «точно в срок» и так далее.

Я думаю, что это был Java, который был первым широко распространенным языком, который действительно замутил разрыв между компилятором и интерпретатором, по иронии судьбы, не для того, чтобы он работал быстрее (хотя и это тоже), а для того, чтобы он работал везде.Определив свой собственный машинный язык и «машинный» байт-код Java и виртуальную машину, Java попыталась стать языком, скомпилированным во что-то близкое к любой базовой машине, но не к реальной машине.

Современные языки объединяют все эти нововведения.Некоторые из них имеют динамичную, открытую природу традиционных «интерпретируемых языков» (Ruby, Lisp, Smalltalk, Python, Perl(!)), «вы не знаете, что получите, пока не получите» (!), некоторые пытаются иметь строгую спецификацию, обеспечивающую глубокое обнаружение статических ошибок на основе типов традиционных компилируемых языков (java, scala).Все они компилируются в реальные машинно-независимые представления (JVM), чтобы получить семантику однократного запуска в любом месте.

Итак, скомпилировано против.интерпретировано?Лучшее из обоих, я бы сказал.Весь код в исходном коде (с документацией), меняйте что угодно, и эффект будет немедленным, простые операции выполняются почти так же быстро, как их может выполнять оборудование, сложные поддерживаются и достаточно быстры, модели оборудования и памяти согласованы на всех платформах.

Самая большая полемика в сегодняшних языках, вероятно, заключается в том, являются ли они статически или динамически типизированными, то есть не то, как быстро они будут работать, а будут ли ошибки обнаружены компилятором заранее (за счет того, что программисту придется указывать довольно сложную типизацию). информация) или же возникнут ошибки при тестировании и производстве.

Вы можете запускать программы Ruby в интерактивном режиме, используя ИРБ, Интерактивная оболочка Ruby.Хотя он может генерировать промежуточный байт-код, он определенно не является «компилятором» в традиционном смысле этого слова.

Компилируемый язык обычно компилируется в машинный код, а не просто в байтовый код.Однако некоторые генераторы байт-кода могут дополнительно скомпилировать байт-код в машинный код.

Байт-код сам по себе является всего лишь промежуточным шагом между буквальным кодом, написанным пользователем и виртуальной машиной, однако он все равно должен интерпретироваться виртуальной машиной (как это происходит с Java в JVM и PHP с кешем кода операции).

Возможно это немного не по теме, но...

Железный Рубин представляет собой реализацию Ruby на основе .net и поэтому обычно компилируется в байт-код, а затем JIT-компилируется в машинный язык во время выполнения (т.е.не интерпретируется).Также (по крайней мере, с другими языками .net, я предполагаю, что с Ruby) нген может использоваться для предварительной генерации скомпилированного собственного двоичного файла, так что по сути это версия Ruby-кода, скомпилированная машинным кодом.

Что касается информации, которую я получил на RubyConf 2011 в Шанхае, Matz разрабатывает «MRuby» (расшифровывается как Matz's Ruby) для работы на встраиваемых устройствах.И Матц сказал, что MRuby предоставит возможность компилировать код Ruby в машинный код, чтобы повысить скорость и уменьшить использование (ограниченных) ресурсов на встроенных устройствах.Итак, существуют различные реализации Ruby, и определенно не все из них просто интерпретируются во время выполнения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top