diff --git a/.rubocop.yml b/.rubocop.yml index e62aa6e..61625b1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -28,6 +28,14 @@ Style/SingleLineMethods: Style/StderrPuts: Enabled: false +Style/GlobalVars: + Exclude: + - mrblib/rf/container.rb + +Style/SpecialGlobalVars: + Exclude: + - mrblib/rf/container.rb + Security/YAMLLoad: Enabled: false @@ -43,6 +51,14 @@ Naming/MemoizedInstanceVariableName: Exclude: - mrblib/rf/container.rb +Naming/MethodName: + Exclude: + - mrblib/rf/container.rb + +Naming/VariableName: + Exclude: + - mrblib/rf/container.rb + RSpec/ContextWording: Prefixes: - when diff --git a/README.md b/README.md index b067063..d4a66b2 100644 --- a/README.md +++ b/README.md @@ -177,13 +177,10 @@ In rf, you can use [special variables](https://docs.ruby-lang.org/ja/latest/clas | Variable name | Description | |-------|------| -| \_ | The input record | -| $\_ | Same as \_ | -| $F | It is an array that stores fields(`$F=_.split`) | -| \_0 | Same as \_ | +| record, \_, $\_, \_0 | The input record | +| fields, $F | It is an array that stores fields(`$F=_.split`) | | \_1, \_2, \_3, ... | First field, second field, third field... | -| $. | The number of records loaded(1-indexed) | -| @NR | Same as $. | +| $., @NR | The number of records loaded(1-indexed) | ## Built-in methods diff --git a/README_ja.md b/README_ja.md index 7f3cf22..dbc9f9d 100644 --- a/README_ja.md +++ b/README_ja.md @@ -184,13 +184,10 @@ rfではRubyで定義されている[特殊変数](https://docs.ruby-lang.org/ja | 変数名 | 説明 | |-------|------| -| \_ | 入力されたレコードです | -| $\_ | \_ のエイリアスです | -| $F | フィールドを格納した配列です(`$F=_.split`) | -| \_0 | \_ と等価です | +| record, \_, $\_, \_0 | 入力されたレコードです | +| fields, $F | フィールドを格納した配列です(`fields=_.split`) | | \_1, \_2, \_3, ... | 1番目、2番目、3番目のフィールドです | -| $. | 1始まりの読み込んだレコード数です | -| @NR | $.と同じです | +| $., @NR | 1始まりの読み込んだレコード数です | ## 組み込みメソッド diff --git a/mrblib/rf/00filter/base.rb b/mrblib/rf/00filter/base.rb index d33dade..e6e1dea 100644 --- a/mrblib/rf/00filter/base.rb +++ b/mrblib/rf/00filter/base.rb @@ -4,7 +4,7 @@ class Base attr_reader :data, :record, :index, :fields def each_record - index = 0 + index = 1 data.each do |record| @record = preprocess(record) @index = index diff --git a/mrblib/rf/cli.rb b/mrblib/rf/cli.rb index 81a0441..cfafd0c 100644 --- a/mrblib/rf/cli.rb +++ b/mrblib/rf/cli.rb @@ -30,14 +30,12 @@ def pre_action def do_action filter.each_record do |record, index, fields| - container._ = record - container.NR = $. = index + 1 - $F = fields # rubocop:disable Style/GlobalVars + container.record = record + container.NR = index + container.fields = fields ret = bind.eval(command) - next if config.quiet - - filter.output(ret) + filter.output(ret) unless config.quiet end end diff --git a/mrblib/rf/container.rb b/mrblib/rf/container.rb index bcb09db..40f6e6b 100644 --- a/mrblib/rf/container.rb +++ b/mrblib/rf/container.rb @@ -1,14 +1,31 @@ module Rf class Container def _ - $_ # rubocop:disable Style/SpecialGlobalVars + $_ end def _=(data) $_ = data end - attr_accessor :NR # rubocop:disable Naming/MethodName + alias record _ + alias record= _= + + def fields + $F + end + + def fields=(data) + $F = data + end + + def NR + @NR ||= 1 + end + + def NR=(num) + @NR = $. = num + end def string? _.instance_of?(String) @@ -41,7 +58,7 @@ def method_missing(sym, *) if sym == :_0 _ elsif s =~ /\A_[1-9]\d*\z/ - $F[s[1..].to_i - 1] # rubocop:disable Style/GlobalVars + $F[s[1..].to_i - 1] else super end diff --git a/spec/special_variables_spec.rb b/spec/special_variables_spec.rb index 9b798bb..ea9502b 100644 --- a/spec/special_variables_spec.rb +++ b/spec/special_variables_spec.rb @@ -1,133 +1,109 @@ describe 'Special Variables' do - describe '$_' do - let(:input) { 'foo' } - let(:output) { input } - - before { run_rf('-q "puts $_"', input) } - - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } - end + context 'for record variables' do + where(:name) do + %w[record $_ _ _0] + end - describe '_' do - let(:input) { 'foo' } - let(:output) { input } + with_them do + let(:input) { 'foo' } + let(:output) { input } - before { run_rf('-q "puts _"', input) } + before { run_rf("-q 'puts #{name}'", input) } - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } + it { expect(last_command_started).to be_successfully_executed } + it { expect(last_command_started).to have_output output_string_eq output } + end end - describe '_0' do - let(:input) { 'foo' } - let(:output) { input } - - before { run_rf('-q "puts _0"', input) } + context 'for fields variables' do + where(:name) do + %w[fields $F] + end - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } - end + with_them do + context 'when record is String' do + let(:input) { 'foo bar baz' } + let(:output) do + <<~OUTPUT + "foo" + "bar" + "baz" + OUTPUT + end + + before { run_rf('-q "p $F[0],$F[1],$F[2]"', input) } + + it { expect(last_command_started).to be_successfully_executed } + it { expect(last_command_started).to have_output output_string_eq output } + end - describe '$F' do - context 'when record is String' do - let(:input) { 'foo bar baz' } - let(:output) do - <<~OUTPUT - "foo" - "bar" - "baz" - OUTPUT + context 'when record is Hash' do + let(:input) do + <<~JSON + { + "a": 1, + "b": 2, + "c": 3 + } + JSON + end + let(:output) do + <<~OUTPUT + ["a", 1] + ["b", 2] + ["c", 3] + OUTPUT + end + + before { run_rf("-j -q 'p #{name}[0],#{name}[1],#{name}[2]'", input) } + + it { expect(last_command_started).to be_successfully_executed } + it { expect(last_command_started).to have_output output_string_eq output } end - before { run_rf('-q "p $F[0],$F[1],$F[2]"', input) } + context 'when record is Other class' do + let(:input) { '1' } + let(:output) do + <<~OUTPUT + 1 + nil + nil + OUTPUT + end - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } - end + before { run_rf("-j -q 'p #{name}[0],#{name}[1],#{name}[2]'", input) } - context 'when record is Hash' do - let(:input) do - <<~JSON - { - "a": 1, - "b": 2, - "c": 3 - } - JSON + it { expect(last_command_started).to be_successfully_executed } + it { expect(last_command_started).to have_output output_string_eq output } end - let(:output) do - <<~OUTPUT - ["a", 1] - ["b", 2] - ["c", 3] - OUTPUT - end - - before { run_rf('-j -q "p $F[0],$F[1],$F[2]"', input) } + end + end - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } + context 'for number of records' do + where(:name) do + %w[$. NR] end - context 'when record is Other class' do - let(:input) { '1' } + with_them do + let(:input) do + <<~TEXT + foo + bar + baz + TEXT + end let(:output) do <<~OUTPUT - 1 - nil - nil + 1 foo + 2 bar + 3 baz OUTPUT end - before { run_rf('-j -q "p $F[0],$F[1],$F[2]"', input) } + before { run_rf(%q/'[$.,_].join(" ")'/, input) } it { expect(last_command_started).to be_successfully_executed } it { expect(last_command_started).to have_output output_string_eq output } end end - - describe '$.' do - let(:input) do - <<~TEXT - foo - bar - baz - TEXT - end - let(:output) do - <<~OUTPUT - 1 foo - 2 bar - 3 baz - OUTPUT - end - - before { run_rf(%q/'[$.,_].join(" ")'/, input) } - - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } - end - - describe '@NR' do - let(:input) do - <<~TEXT - foo - bar - baz - TEXT - end - let(:output) do - <<~OUTPUT - 1 foo - 2 bar - 3 baz - OUTPUT - end - - before { run_rf(%q/'[@NR,_].join(" ")'/, input) } - - it { expect(last_command_started).to be_successfully_executed } - it { expect(last_command_started).to have_output output_string_eq output } - end end