2015-01-04 16 views
5

Mam tablicę w języku Ruby ze wszystkimi słowami kluczowymi.Programowy sposób uzyskiwania słów kluczowych w Ruby

Na przykład:

RUBY_KEYWORDS = %w(

    alias and BEGIN begin break case class def defined 
    do else elsif END end ensure false for if in module 
    next nil not or redo rescue retry return self super 
    then true undef unless until when while yield 

) 

Moje pytanie jest prosta:

Czy jest wbudowany sposób programowo dostęp do wszystkich słów kluczowych?

Niektóre z moich projektów trzeba uruchomić kwerendę przeciwko wejścia użytkownika, i jest to trochę irytujące, aby zdefiniować tę samą tablicę w wszystkich tych projektów.

+0

Jakie zapytania Biegasz? Dlaczego musisz sprawdzić dane wejściowe w odniesieniu do tej listy słów kluczowych? Czy "eval" to wejście? A co z innymi metodami Rubiego, które mogą być niebezpieczne (np. 'FileUtils.rm_r')? – spickermann

+1

Podsumowuję poprzednie pytanie cytatem z Matza: "Parser Ruby jest elastyczny i nie narzeka, jeśli przedrostkujesz te słowa kluczowe przedrostkami @, @@ lub $ i używasz ich jako nazw instancji, klas lub zmiennych globalnych. traktuje te słowa kluczowe jako zastrzeżone._ ". Ponadto, jeśli uważasz, że nie powinieneś akceptować danych wejściowych z tymi słowami kluczowymi, może to być błąd. Dlatego powtarzam pytanie: dlaczego potrzebujesz listy słów kluczowych? – romainsalles

Odpowiedz

6

Spróbuj ten kod :)

RubyToken::TokenDefinitions.select { |definition| definition[1] == RubyToken::TkId } 
          .map { |definition| definition[2] } 
          .compact 
          .sort 

# returns : 
# ["BEGIN", "END", "__FILE__", "__LINE__", "alias", "and", "begin", "break", "case", "class", "def", "defined?", "do", "else", "elsif", "end", "ensure", "false", "for", "if", "in", "module", "next", "nil", "not", "or", "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless", "until", "when", "while", "yield"] 
+1

Ciekawe, że [tabela słów kluczowych w źródle ruby] (https://github.com/ruby/ruby/blob/ruby_2_2/defs/keywords) obejmuje '__ENCODING__'. Ten kod zwraca wszystkie oprócz tego. –

+1

Powinieneś chyba wspomnieć, że jest to część biblioteki 'irb' w bibliotece stdlib, a nie w bibliotece rdzeniowej, więc musisz najpierw" wymagać "irb/ruby-tokena. Ponadto dobrze wiadomo, że analizator składni IRb jest błędny, więc wyniki, które tu uzyskasz, niekoniecznie będą pasowały do ​​specyfikacji Ruby. Jest to nieudokumentowane, więc może ulec zmianie bez powiadomienia. –

+0

To wydaje się działać, dziękuję! Będę trzymać się go, dopóki nie pojawi się coś lepszego. :) – shevy

0

Nie sądzę, że można, ponieważ zostanie on zdefiniowany w analizatorze składni.

Twój alternatywą byłoby spojrzeć na kod źródłowy: https://github.com/ruby/ruby/blob/ruby_2_1/defs/keywords

+0

Po pierwsze: 'Object.methods' będzie * nie * pokazywać metody w klasie' Object', pokaże metody, na które odpowiada obiekt 'Object' * *, które są w zasadzie metodami klasy" Class " nie klasa 'Object', ponieważ' Object' jest instancją klasy 'Class'. To, czego chcesz, to 'Object.instance_methods'. Jednak ani 'Object.instance_methods' ani' Object.constants' nie pokażą ci słów kluczowych. Pokaże metody i stałe (duh!) –

+0

Dobrze wiedzieć, zredagowałem odpowiedź. – Pran