2016-09-14 12 views
5

Chciałbym rozszerzyć domyślną aplikację konsoli, która jest standardowo wyposażona w bundle gem, stosując niektóre opcje konfiguracji IRB.Dostosowywanie konsoli IRB do klejnotów

Looking at the documentation, Widzę, że powinno być możliwe na przykład zmienić monit, a to działa poprawnie podczas sesji interaktywnej. Na przykład mogę grać z wyświetlonej wierszu tak:

2.1.4 :001 > conf.prompt_mode=:SIMPLE 
=> :SIMPLE 
>> 
?> conf.prompt_mode=:DEFAULT 
=> :DEFAULT 
irb(main):004:0> 

Jednak nie mogę znaleźć jak przełożyć to na składni do wykorzystania w aplikacji konsoli. Na przykład ten skrypt:

require 'irb' 
IRB.conf[:PROMPT_MODE] = :SIMPLE 
IRB.start 

Właśnie rozpoczyna się ogólnym skonfigurowanego wierszu:

2.1.4 :001 > 

spędziłem trochę czasu próbując znaleźć przykład wykorzystania IRB dla niestandardowego repl bez ładowania globalnych ustawień domyślnych, ale nie znaleziono niczego, z czego mogę skopiować.

Widzę, że nieudokumentowana metoda IRB.setup ma coś z tym wspólnego, to jakoś ustawia całą konfigurację. Czy moja jedyna możliwość napisania własnej wersji IRB.start, która dotyczy mojej pożądanej konfiguracji po wywołaniu IRB.setup, czy też istnieje wsparcie dla tego, co chcę zrobić, ale nie udokumentowane w standardowej lokalizacji?


Np. następujące prace, ale uważam, że w ten sposób jest to trochę ciężko rozbudowywany moduł IRB (a także podatność na błędy w przypadku zmiany wewnętrznych elementów IRB).

require 'irb' 

def IRB.custom_start custom_conf = {} 
    STDOUT.sync = true 

    IRB.setup(nil) 

    custom_conf.each do |k,v| 
    IRB.conf[k] = v 
    end 

    if @CONF[:SCRIPT] 
    irb = IRB::Irb.new(nil, @CONF[:SCRIPT]) 
    else 
    irb = IRB::Irb.new 
    end 

    @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] 
    @CONF[:MAIN_CONTEXT] = irb.context 

    trap("SIGINT") do 
    irb.signal_handle 
    end 

    begin 
    catch(:IRB_EXIT) do 
     irb.eval_input 
    end 
    ensure 
    irb_at_exit 
    end 
end 

IRB.custom_start :PROMPT_MODE => :SIMPLE 

Odpowiedz

2

Możesz zastosować niestandardowe konfiguracje na dwa sposoby.

Pierwszym z nich jest użycie irbrc file. Może to być trudne do zbudowania aplikacji konsoli (wywołanie IRB.start z pliku ruby ​​zamiast z irb z konsoli).

Druga to podejście, które opisałeś w poście. Możesz napisać własną metodę IRB::start opartą na the original one. Istnieją dokładnie takie same potencjalne problemy, jak przy korzystaniu z nieudokumentowanego API - może on pęknąć w przyszłości dzięki nowszym wersjom irb.

Powinieneś się zastanowić, czy naprawdę potrzebujesz zbudować aplikację konsolową na górze irb. Na przykład możesz rozwiązać ten problem, używając Pry. To pozwala na define configuration przed rozpoczęciem sesji interaktywnej.

+1

Dziękuję za ponowne skierowanie mnie na Pry. Patrzyłem na to wcześniej, ale skupienie się na funkcjach debugowania sprawiło, że myślałem, że to nie jest odpowiednie. Może to być dla mnie lepsze niż 'irb', nawet jeśli specjalnie udokumentowane wsparcie dla zmiany konfiguracji programowo. –

1
require 'irb' 
IRB.conf[:PROMPT_MODE] = :SIMPLE 
IRB.start 

Podejście powyżej nie działa, ponieważ conf[:PROMPT_MODE] dostaje zbyt riden w metodzie zwanej IRB.init_confighere

Kiedy IRB.start nazywa, wywołuje IRB.setup co z kolei wywołuje metodę IRB.init_config - który nad- jeździ po ustawieniu conf[:PROMPT_MODE].


Oto jedno podejście, które rozwiązuje problem (polega na wewnętrznej wiedzy na temat realizacji).

require 'irb' 

module IRB 
    singleton_class.send(:alias_method, :old_setup, :setup) 

    def IRB.setup(ap_path) 
    IRB.old_setup(ap_path) 

    conf[:PROMPT_MODE] = :SIMPLE 
    end 
end 

IRB.start 
+0

To jest czystsze niż moje rozwiązanie, ale dzieli problem, który działa z implementacją, a nie z "oficjalnym" interfejsem. –

+0

@NeilSlater Tak, dlatego powiedziałem, że "polega na wewnętrznej wiedzy na temat wdrożenia". Domyślam się, że "setup" jest metodą publiczną, a więc częścią interfejsu publicznego. Po prostu nie jest to udokumentowane. – Rashmirathi

Powiązane problemy