Skip to content

Commit cc676a9

Browse files
koriymclaude
andcommitted
Add demo for Ray.Compiler usage
Create a working demo showing Ray.Compiler's two-phase architecture: compile-time dependency resolution and runtime script execution. Demo structure: - demo/GreeterInterface.php - Service interface - demo/Greeter.php - Service implementation - demo/AppModule.php - Ray.Di module with bindings - demo/compile.php - Compilation script (build time) - demo/run.php - Execution script (runtime) - demo/README.md - Comprehensive documentation Key features demonstrated: 1. Compile bindings into optimized PHP scripts 2. Use CompiledInjector for zero-overhead DI at runtime 3. Generated scripts are simple: new Class() + return 4. No reflection or dependency resolution in production Usage: ```bash php demo/compile.php # Generate scripts php demo/run.php # Execute with compiled DI ``` Changes: - Add demo/ directory with example files - Update composer.json autoload-dev for demo namespace - Add demo/.compiled to .gitignore All tests pass ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 78492de commit cc676a9

File tree

8 files changed

+184
-0
lines changed

8 files changed

+184
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ build
1010
/coverage.xml
1111
*.bak
1212
.claude
13+
/demo/.compiled

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"autoload-dev": {
4040
"psr-4": {
4141
"Ray\\Compiler\\": ["tests", "tests/Fake"],
42+
"Ray\\Compiler\\Demo\\": "demo",
4243
"Ray\\Di\\": "tests/Fake/Assisted"
4344
},
4445
"files": ["tests/deleteFiles.php"]

demo/AppModule.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ray\Compiler\Demo;
6+
7+
use Ray\Di\AbstractModule;
8+
9+
final class AppModule extends AbstractModule
10+
{
11+
protected function configure(): void
12+
{
13+
$this->bind(GreeterInterface::class)->to(Greeter::class);
14+
}
15+
}

demo/Greeter.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ray\Compiler\Demo;
6+
7+
final class Greeter implements GreeterInterface
8+
{
9+
public function __construct(private readonly string $greeting = 'Hello')
10+
{
11+
}
12+
13+
public function greet(string $name): string
14+
{
15+
return sprintf('%s, %s!', $this->greeting, $name);
16+
}
17+
}

demo/GreeterInterface.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ray\Compiler\Demo;
6+
7+
interface GreeterInterface
8+
{
9+
public function greet(string $name): string;
10+
}

demo/README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Ray.Compiler Demo
2+
3+
This demo shows how Ray.Compiler pre-compiles dependency injection bindings into executable PHP scripts.
4+
5+
## Architecture
6+
7+
Ray.Compiler uses a **two-phase architecture**:
8+
9+
### Compile-time (Development/Build)
10+
- Uses Ray.Di's full dependency resolution
11+
- Analyzes bindings, constructs dependency graph
12+
- Generates optimized PHP scripts
13+
14+
### Runtime (Production)
15+
- Uses minimal `CompiledInjector`
16+
- Executes pre-compiled scripts
17+
- **No reflection, no dependency resolution**
18+
19+
## Files
20+
21+
- `GreeterInterface.php` - Service interface
22+
- `Greeter.php` - Service implementation
23+
- `AppModule.php` - Dependency injection bindings
24+
- `compile.php` - Compilation script (run at build time)
25+
- `run.php` - Execution script (uses compiled scripts)
26+
27+
## Usage
28+
29+
### Step 1: Compile (Build Time)
30+
31+
```bash
32+
php demo/compile.php
33+
```
34+
35+
This generates optimized PHP scripts in `demo/.compiled/`:
36+
- `Ray_Compiler_Demo_GreeterInterface-.php`
37+
- Other dependency scripts
38+
39+
### Step 2: Run (Runtime)
40+
41+
```bash
42+
php demo/run.php
43+
```
44+
45+
Output:
46+
```
47+
Hello, World!
48+
Hello, Ray.Compiler!
49+
50+
✓ Using pre-compiled dependency injection!
51+
✓ No reflection, no dependency resolution at runtime
52+
✓ Check demo/.compiled/ for generated PHP scripts
53+
```
54+
55+
## Inspecting Generated Code
56+
57+
After compilation, check the generated scripts:
58+
59+
```bash
60+
cat demo/.compiled/Ray_Compiler_Demo_GreeterInterface-.php
61+
```
62+
63+
You'll see plain PHP code that instantiates objects - no complex DI logic!
64+
65+
## Benefits
66+
67+
1. **Performance**: No runtime reflection or dependency resolution
68+
2. **Zero Overhead**: Compiled scripts are simple `new` and `return` statements
69+
3. **Debuggable**: Generated code is readable PHP
70+
4. **Production Ready**: No heavy DI framework in production
71+
72+
## How It Works
73+
74+
```
75+
┌─────────────────┐ ┌──────────────┐
76+
│ Ray.Di Module │────────▶│ Compiler │
77+
│ (Bindings) │ │ │
78+
└─────────────────┘ └──────┬───────┘
79+
80+
81+
┌──────────────┐
82+
│ PHP Scripts │
83+
│ (Optimized) │
84+
└──────┬───────┘
85+
86+
87+
┌──────────────────┐
88+
│ CompiledInjector │
89+
│ (Lightweight) │
90+
└──────────────────┘
91+
```
92+
93+
## Next Steps
94+
95+
- Add more complex dependencies (interfaces, providers, AOP)
96+
- Try scopes (singleton vs prototype)
97+
- Explore assisted injection
98+
- Use with your real application modules

demo/compile.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Ray\Compiler\Compiler;
6+
use Ray\Compiler\Demo\AppModule;
7+
8+
require dirname(__DIR__) . '/vendor/autoload.php';
9+
10+
$scriptDir = __DIR__ . '/.compiled';
11+
$module = new AppModule();
12+
13+
// Compile the dependency injection container
14+
$compiler = new Compiler();
15+
$compiler->compile($module, $scriptDir);
16+
17+
echo "✓ Compilation complete! Scripts saved to: {$scriptDir}\n";
18+
echo "✓ Run 'php demo/run.php' to execute the compiled application\n";

demo/run.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Ray\Compiler\CompiledInjector;
6+
use Ray\Compiler\Demo\GreeterInterface;
7+
8+
require dirname(__DIR__) . '/vendor/autoload.php';
9+
10+
$scriptDir = __DIR__ . '/.compiled';
11+
12+
// Use the compiled injector (no Ray.Di runtime overhead)
13+
$injector = new CompiledInjector($scriptDir);
14+
15+
/** @var GreeterInterface $greeter */
16+
$greeter = $injector->getInstance(GreeterInterface::class);
17+
18+
echo $greeter->greet('World') . "\n";
19+
echo $greeter->greet('Ray.Compiler') . "\n";
20+
21+
echo "\n";
22+
echo "✓ Using pre-compiled dependency injection!\n";
23+
echo "✓ No reflection, no dependency resolution at runtime\n";
24+
echo "✓ Check {$scriptDir}/ for generated PHP scripts\n";

0 commit comments

Comments
 (0)