Подтвердить что ты не робот

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

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

Весь текущий Ruby реализации скомпилированы для байткод. В отличие от заявлений SAP, поскольку Ruby 1.9, MRI включает в себя байт-код, хотя способность для сохранения скомпилированного байт-кода на диск исчезли где-то в процессе слияния виртуальной машины YARV. JRuby скомпилирован в Java.class файлы. У меня нет подробностей на MagLev, но, кажется, безопасно это сказать будет также проходить по этой дороге.

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

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

Различие, по сути, возвращение к, возможно, концу 70, было не так много между скомпилированными и интерпретируемыми языками, но были ли они запущены в скомпилированной или интерпретируемой среде. Например, Паскаль (первый язык высокого уровня, который я изучал) работал в UC Berkeley сначала на интерпретаторе Bill Joy pxp, а позже на компиляторе он написал pcc. Тот же язык, доступный как в скомпилированных, так и в интерпретируемых средах.

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

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

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

Современные языки выходят замуж за все эти нововведения. Некоторые из них имеют динамический, открытый, традиционный, несовместимый характер традиционных "интерпретируемых языков" (ruby, Lisp, smalltalk, python, perl (!)), Некоторые старайтесь иметь строгость спецификации, позволяя обнаруживать статические ошибки на основе статического языка традиционных скомпилированных языков (java, scala). Все компилируются для реальных машинно-независимых представлений (JVM), чтобы получить одноразовую одностороннюю семантику записи.

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

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

Ответ 4

Вы можете запускать программы Ruby интерактивно, используя irb, Interactive Ruby Shell. Хотя он может генерировать промежуточный байт-код, это, конечно, не "компилятор" в традиционном смысле.

Ответ 5

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

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

Ответ 6

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

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

Ответ 7

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