Module: Musa::REPL::CustomizableDSLContext
- Defined in:
- lib/musa-dsl/repl/repl.rb
Overview
Mixin for DSL contexts that can be bound to a REPL.
This module provides the interface required for a DSL context to work with the REPL server. Classes that include this module can execute REPL-sent code in their own context, making their DSL methods available to live coding clients.
Requirements
Classes that include this module must implement the #binder method, which should return a Ruby Binding object representing the execution context.
Integration with DynamicProxy
Typically used with Musa::Extension::DynamicProxy::DynamicProxy:
class MyDSL
include CustomizableDSLContext
def initialize
@repl = REPL.new(Musa::Extension::DynamicProxy::DynamicProxy.new(self))
end
protected def binder
@__binder ||= binding
end
# DSL methods available in REPL:
def play(note)
# ...
end
end
Execution Context
Code sent via REPL is evaluated in the binding returned by #binder, giving it access to:
- Instance variables of the DSL context
- All DSL methods (public and private)
- Local variables captured in the binding
A live coding environment built on it (a reading: it starts a listening server in its constructor):
class LiveCodingEnvironment
include Musa::REPL::CustomizableDSLContext
def initialize
@sequencer = Musa::Sequencer::Sequencer.new(4, 24)
@repl = REPL.new(Musa::Extension::DynamicProxy::DynamicProxy.new(self))
end
protected def binder
@__binder ||= binding
end
# DSL methods accessible from REPL:
def at(position, &block)
@sequencer.at(position, &block)
end
end
And what the editor then sends, which executes in that instance's context:
at(1) { play C4 }
at(4) { play D4 }
Instance Method Summary collapse
-
#execute(source_block, file, line) ⇒ Object
Executes source code in the DSL context.
Instance Method Details
#execute(source_block, file, line) ⇒ Object
Executes source code in the DSL context.
Called by the REPL to evaluate received code blocks. Delegates to Binding#eval with the binding provided by #binder.
Parameters
- source_block: Ruby code as string
- file: Filename for error reporting (typically '(repl)')
- line: Starting line number for error reporting
Error Handling
Exceptions raised during evaluation propagate to the caller (REPL), which formats them and sends them to the client.
How the REPL calls it (a reading: context is the bound DSL context):
context.execute("sequencer.at(1) { puts 'tick' }", "(repl)", 1)
760 761 762 |
# File 'lib/musa-dsl/repl/repl.rb', line 760 def execute(source_block, file, line) binder.eval source_block, file, line end |