Skip to content

Commit

Permalink
Implement Kernel#`
Browse files Browse the repository at this point in the history
  • Loading branch information
herwinw committed Jul 10, 2024
1 parent f753340 commit 3874e3f
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 39 deletions.
1 change: 1 addition & 0 deletions include/natalie/kernel_module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class KernelModule : public Object {
static Value Array(Env *env, Value value);
static Value abort_method(Env *env, Value message);
static Value at_exit(Env *env, Block *block);
static Value backtick(Env *, Value);
static Value binding(Env *env);
static Value caller(Env *env, Value start = nullptr, Value length = nullptr);
static Value caller_locations(Env *env, Value start = nullptr, Value length = nullptr);
Expand Down
1 change: 1 addition & 0 deletions lib/natalie/compiler/binding_gen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ def generate_name
gen.binding('IO', 'write', 'IoObject', 'write', argc: :any, pass_env: true, pass_block: false, return_type: :Object)
gen.binding('IO', 'write_nonblock', 'IoObject', 'write_nonblock', argc: 1, kwargs: [:exception], pass_env: true, pass_block: false, return_type: :Object)

gen.module_function_binding('Kernel', '`', 'KernelModule', 'backtick', argc: 1, pass_env: true, pass_block: false, return_type: :Object)
gen.module_function_binding('Kernel', 'Array', 'KernelModule', 'Array', argc: 1, pass_env: true, pass_block: false, return_type: :Object)
gen.module_function_binding('Kernel', 'abort', 'KernelModule', 'abort_method', argc: 0..1, pass_env: true, pass_block: false, return_type: :Object)
gen.module_function_binding('Kernel', 'at_exit', 'KernelModule', 'at_exit', argc: 0, pass_env: true, pass_block: true, return_type: :Object)
Expand Down
1 change: 0 additions & 1 deletion lib/natalie/compiler/instructions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
require_relative './instructions/retry_instruction'
require_relative './instructions/return_instruction'
require_relative './instructions/send_instruction'
require_relative './instructions/shell_instruction'
require_relative './instructions/singleton_class_instruction'
require_relative './instructions/string_append_instruction'
require_relative './instructions/string_to_regexp_instruction'
Expand Down
1 change: 0 additions & 1 deletion lib/natalie/compiler/instructions/meta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ class Compiler
RetryInstruction,
ReturnInstruction,
SendInstruction,
ShellInstruction,
SingletonClassInstruction,
StringAppendInstruction,
StringToRegexpInstruction,
Expand Down
21 changes: 0 additions & 21 deletions lib/natalie/compiler/instructions/shell_instruction.rb

This file was deleted.

20 changes: 18 additions & 2 deletions lib/natalie/compiler/pass1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1890,8 +1890,16 @@ def transform_interpolated_symbol_node(node, used:)

def transform_interpolated_x_string_node(node, used:)
instructions = [
PushSelfInstruction.new,
transform_interpolated_stringish_node(node, used: true, unescaped: false),
ShellInstruction.new
PushArgcInstruction.new(1),
SendInstruction.new(
:`,
receiver_is_self: true,
with_block: false,
file: @file.path,
line: node.location.start_line,
)
]
instructions << PopInstruction.new unless used
instructions
Expand Down Expand Up @@ -2616,8 +2624,16 @@ def transform_while_node(node, used:)

def transform_x_string_node(node, used:)
instructions = [
PushSelfInstruction.new,
PushStringInstruction.new(node.unescaped),
ShellInstruction.new,
PushArgcInstruction.new(1),
SendInstruction.new(
:`,
receiver_is_self: true,
with_block: false,
file: @file.path,
line: node.location.start_line,
)
]
instructions << PopInstruction.new unless used
instructions
Expand Down
23 changes: 9 additions & 14 deletions spec/core/kernel/backtick_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@
end

it "is a private method" do
NATFIXME 'Convert ` to method on Kernel', exception: SpecFailedException do
Kernel.should have_private_instance_method(:`)
end
Kernel.should have_private_instance_method(:`)
end

it "returns the standard output of the executed sub-process" do
ip = 'world'
`echo disc #{ip}`.should == "disc world\n"
end

it "lets the standard error stream pass through to the inherited stderr" do
NATFIXME 'it lets the standard error stream pass through to the inherited stderr', exception: SpecFailedException do
cmd = ruby_cmd('STDERR.print "error stream"')
-> {
`#{cmd}`.should == ""
}.should output_to_fd("error stream", STDERR)
end
# NATFIXME: Issues with capturing stderr stream?
xit "lets the standard error stream pass through to the inherited stderr" do
cmd = ruby_cmd('STDERR.print "error stream"')
-> {
`#{cmd}`.should == ""
}.should output_to_fd("error stream", STDERR)
end

it "produces a String in the default external encoding" do
Expand Down Expand Up @@ -90,9 +87,7 @@

describe "Kernel.`" do
it "tries to convert the given argument to String using #to_str" do
NATFIXME 'Convert ` to method on Kernel', exception: NoMethodError, message: "undefined method ``' for module Kernel" do
(obj = mock('echo test')).should_receive(:to_str).and_return("echo test")
Kernel.`(obj).should == "test\n" #` fix vim syntax highlighting
end
(obj = mock('echo test')).should_receive(:to_str).and_return("echo test")
Kernel.`(obj).should == "test\n" #` fix vim syntax highlighting
end
end
4 changes: 4 additions & 0 deletions src/kernel_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ Value KernelModule::at_exit(Env *env, Block *block) {
return proc;
}

Value KernelModule::backtick(Env *env, Value command) {
return shell_backticks(env, command->to_str(env));
}

Value KernelModule::binding(Env *env) {
return new BindingObject { env };
}
Expand Down

0 comments on commit 3874e3f

Please sign in to comment.