Class: FileOverwrite
- Inherits:
-
Object
- Object
- FileOverwrite
- Includes:
- FileUtils
- Defined in:
- lib/file_overwrite/file_overwrite.rb
Overview
Controller class to backup a file and overwrite it
Ruby iterators and chaining-methods are fully exploited to edit the file.
Examples
f1 = FileOverwrite.new('a.txt', noop: true, verbose: true)
# Treat the content as String
f1.sub(/abc/, 'xyz').gsub(/(.)ef/){|i| $1}.run!
f1.sizes # => { :old => 40, :new => 50 }
f1.backup # => 'a.txt.20180915.bak'
# However, the file has not been created
# and the original file has not been modified, either,
# due to the noop option
f2 = FileOverwrite.new('a.txt', suffix: '~')
f2.backup # => 'a.txt~'
f2.completed? # => false
# Treat the content as String inside the block
f2.read{ |str| "\n" + i + "\n" }.gsub(/a\nb/m, '').run!
f2.completed? # => true
FileOverwrite.new('a.txt', suffix: '~').sub(/a/, '').run!
# => RuntimeError, because the backup file 'a.txt~' exists.
FileOverwrite.new('a.txt', suffix: '~').sub(/a/, '').run!(clobber: true)
# => The backup file is overwritten.
f3 = FileOverwrite.new('a.txt', backup: '/tmp/b.txt')
# Backup file can be explicitly specified.
f3.backup # => '/tmp/b.txt'
f3.backup = 'original.txt'
f3.backup # => 'original.txt'
# Treat the file as IO inside the block
f3.open{ |ior, iow| i + "XYZ" }
f3.reset # The modification is discarded
f3.reset? # => true
f3.open{ |ior, iow| i + "XYZ"; raise FileOverwriteError, 'I stop.' }
# To discard the modification inside the block
f3.reset? # => true
f3.open{ |ior, iow| "\n" + i + "\n" }
f3.run!(noop: true, verbose: true) # Dryrun
f3.completed? # => true
f3.backup = 'change.d' # => FrozenError (the state can not be modified after run!(), including dryrun)
f4 = FileOverwrite.new('a.txt', suffix: nil)
f4.backup # => nil (No backup file is created.)
f4.readlines{|ary| ary+["last\n"]}.each{|i| 'XX'+i}.run!
IO.readlines('a.txt')[-1] # => "XXlast\n"
f5 = FileOverwrite.new('a.txt', suffix: '.bak')
f5.backup # => 'a.txt.bak'
f5.read{|i| i}.run!
FileUtils.identical? 'a.txt', 'a.txt.bak' # => true
File.mtime('a.txt') == File.mtime('a.txt.bak') # => true
# To forcibly update the Timestamp, give touch option as true
# either in new() or run!(), ie., run!(touch: true)
Instance Attribute Summary collapse
-
#backup(suffix = nil, backupfile: nil) ⇒ String, NilClass
Gets a path of the filename for backup.
- #ext_enc ⇒ Encoding
-
#ext_enc_new ⇒ Object
Encoding of the content of the output file.
-
#ext_enc_old ⇒ Object
Encoding of the content of the input file.
- #int_enc ⇒ Encoding
-
#sizes ⇒ Object
readonly
Hash of the file sizes of before (:old) and after (:new).
- #verbose ⇒ Boolean
Class Method Summary collapse
-
.readlines(fname, *rest, **kwd) { ... } ⇒ FileOverwrite
Shorthand of #initialize.#readlines, taking parameters for both.
-
.readlines!(*rest, **kwd) { ... } ⇒ FileOverwrite
Shorthand of FileOverwrite.readlines.#run!.
Instance Method Summary collapse
-
#chainable? ⇒ Boolean, NilClass
Returns true if the instance is chainable.
-
#completed? ⇒ Boolean
Returns true if the process has been completed.
-
#dump ⇒ String
Returns the (current) content as String to supercede the input file.
-
#each_line(*rest, **kwd) {|str| ... } ⇒ self
Takes a block in which each line of the file (or current content) is passed.
- #each_line!(*rest, **kwd) { ... } ⇒ self
-
#empty? ⇒ String
True if the (current) content to supercede the input file is empty.
-
#encode(*rest, **kwd) ⇒ String
Implement String#encode.
-
#end_with?(*rest) ⇒ String
True if the (current) content to supercede the input file end with the specified.
-
#force_encoding(enc) ⇒ Encoding
Implement String#force_encoding.
-
#fresh? ⇒ Boolean
(also: #reset?)
Returns true if the process has not yet started.
-
#gsub(*rest, max: 0, **kwd) { ... } ⇒ self
Similar to String#gsub.
- #gsub!(*rest, **kwd) { ... } ⇒ self
-
#initialize(fname, backup: nil, suffix: true, noop: false, verbose: $VERBOSE, clobber: false, touch: false) ⇒ FileOverwrite
constructor
A new instance of FileOverwrite.
-
#modify(**kwd) {|ioin, @iotmp| ... } ⇒ self
(also: #open)
Modify the content in the block (though not committed, yet).
- #modify!(**kwd) {|ioin, @iotmp| ... } ⇒ self (also: #open!)
-
#read(**kwd) {|str| ... } ⇒ self
Handler to process the entire string of the file (or current content).
- #read!(**kwd) { ... } ⇒ self
-
#readlines(*rest, **kwd) {|str| ... } ⇒ self
Takes a block in which the entire String of the file is passed.
-
#ready? ⇒ Boolean
Returns true if the instance is ready to run (to execute overwriting the file).
-
#replace_with(str) ⇒ self
Similar to String#replace but the original is not modified.
-
#replace_with!(str, **kwd) { ... } ⇒ self
Alias to self.#replace_with.#run!.
-
#reset ⇒ NilClass
Reset all the modification which is to be applied.
-
#run!(backup: @backup, suffix: @suffix, noop: @noop, verbose: @verbose, clobber: @clobber, touch: @touch, setsize: true, **kwd) ⇒ NilClass, self
(also: #run)
Actually performs the file modification.
-
#state ⇒ Class, ...
Returns the current state.
-
#sub(*rest, max: 1, **kwd) { ... } ⇒ self
Similar to String#sub.
- #sub!(*rest, **kwd) { ... } ⇒ self
-
#temporary_filename ⇒ String, NilClass
Returns the temporary filename (or nil), maybe for debugging.
-
#tr(*rest, **kwd) ⇒ self
Similar to String#tr.
- #tr!(*rest, **kwd) ⇒ self
-
#tr_s(*rest, **kwd) ⇒ self
Similar to String#tr_s.
- #tr_s!(*rest, **kwd) ⇒ self
-
#valid_encoding? ⇒ Boolean, NilClass
String#valid_encoding?().
Constructor Details
#initialize(fname, backup: nil, suffix: true, noop: false, verbose: $VERBOSE, clobber: false, touch: false) ⇒ FileOverwrite
Returns a new instance of FileOverwrite.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/file_overwrite/file_overwrite.rb', line 115 def initialize(fname, backup: nil, suffix: true, noop: false, verbose: $VERBOSE, clobber: false, touch: false) @fname = fname @backup = backup @suffix = (backup ? true : suffix) @noop = noop @verbose = $DEBUG || verbose @clobber = clobber @touch = touch @ext_enc_old = nil @ext_enc_new = nil @int_enc = nil @outstr = nil # String to write. This is nil if the temporary file was already created with modify(). @outary = nil # or Array to write @iotmp = nil # Temporary file IO to replace the original @is_edit_finished = false # true if the file modification is finished. @is_completed = false # true after all the process has been completed. @sizes = nil end |
Instance Attribute Details
#backup(suffix = nil, backupfile: nil) ⇒ String, NilClass
Gets a path of the filename for backup
If suffix is given, the default suffix and backup filename are ignored, and the (backup) filename with the given suffix is returned (so you can tell what the backup filename would be if the suffix was set).
149 150 151 152 153 154 155 |
# File 'lib/file_overwrite/file_overwrite.rb', line 149 def backup(suffix=nil, backupfile: nil) return backup_from_suffix(suffix) if suffix # non-nil suffix explicitly given return backupfile if backupfile return @backup if @backup return backup_from_suffix(@suffix) if @suffix nil end |
#ext_enc ⇒ Encoding
96 |
# File 'lib/file_overwrite/file_overwrite.rb', line 96 attr_accessor :ext_enc_old |
#ext_enc_new ⇒ Object
Encoding of the content of the output file. Default is nil (unspecified).
101 102 103 |
# File 'lib/file_overwrite/file_overwrite.rb', line 101 def ext_enc_new @ext_enc_new end |
#ext_enc_old ⇒ Object
Encoding of the content of the input file. Default is nil (unspecified).
96 97 98 |
# File 'lib/file_overwrite/file_overwrite.rb', line 96 def ext_enc_old @ext_enc_old end |
#int_enc ⇒ Encoding
106 107 108 |
# File 'lib/file_overwrite/file_overwrite.rb', line 106 def int_enc @int_enc end |
#sizes ⇒ Object (readonly)
86 87 88 |
# File 'lib/file_overwrite/file_overwrite.rb', line 86 def sizes @sizes end |
#verbose ⇒ Boolean
91 92 93 |
# File 'lib/file_overwrite/file_overwrite.rb', line 91 def verbose @verbose end |
Class Method Details
.readlines(fname, *rest, **kwd) { ... } ⇒ FileOverwrite
Shorthand of #initialize.#readlines, taking parameters for both
831 832 833 |
# File 'lib/file_overwrite/file_overwrite.rb', line 831 def self.readlines(fname, *rest, **kwd, &bloc) new(fname, *rest, **kwd).send(__method__, *rest, **kwd, &bloc) end |
.readlines!(*rest, **kwd) { ... } ⇒ FileOverwrite
842 843 844 |
# File 'lib/file_overwrite/file_overwrite.rb', line 842 def self.readlines!(*rest, **kwd, &bloc) readlines(*rest, **kwd, &bloc).run!(**kwd) end |
Instance Method Details
#chainable? ⇒ Boolean, NilClass
164 165 166 167 168 |
# File 'lib/file_overwrite/file_overwrite.rb', line 164 def chainable? return nil if fresh? return false if completed? return !@is_edit_finished # ie., (@outary || @outstr) b/c one of the three must be non-false after the 2 clauses above. end |
#completed? ⇒ Boolean
Returns true if the process has been completed.
172 173 174 |
# File 'lib/file_overwrite/file_overwrite.rb', line 172 def completed? @is_completed end |
#dump ⇒ String
Returns the (current) content as String to supercede the input file
If the file has been already overwritten, this returns the content of the new one. Note it would be impossible to return the old one anyway, if no backup is left, as the user chooses.
Even if the returned string is destructively modified, it has no effect on the final output to the overwritten file.
187 188 189 190 191 192 |
# File 'lib/file_overwrite/file_overwrite.rb', line 187 def dump return @outstr.dup if @outstr return join_outary() if @outary return File.read(@iotmp.path) if @is_edit_finished File.read(@fname) end |
#each_line(*rest, **kwd) {|str| ... } ⇒ self
Takes a block in which each line of the file (or current content) is passed.
In the block each line as String is given as a block argument. Each iterator must return a String (or an object having to_s method), which replaces the input String to be output to the overwritten file later.
This method can be chained, as String-type processing.
544 545 546 547 548 549 |
# File 'lib/file_overwrite/file_overwrite.rb', line 544 def each_line(*rest, **kwd, &bloc) raise ArgumentError, 'Block must be given.' if !block_given? read(**kwd){ |outstr| outstr.each_line(*rest).map{|i| yield(i).to_s}.join('') } end |
#each_line!(*rest, **kwd) { ... } ⇒ self
557 558 559 |
# File 'lib/file_overwrite/file_overwrite.rb', line 557 def each_line!(*rest, **kwd, &bloc) send(__method__.to_s.chop, *rest, **kwd, &bloc).run!(**kwd) end |
#empty? ⇒ String
True if the (current) content to supercede the input file is empty.
198 199 200 |
# File 'lib/file_overwrite/file_overwrite.rb', line 198 def empty? dump.empty? end |
#encode(*rest, **kwd) ⇒ String
Implement String#encode
If it is in the middle of the process, the internal encoding for String (or Array) changes. Note if the current proces is in the IO-mode, everything has been already written in a temporary file, and hence there is no effect.
Once this is called, @int_enc is overwritten (or set), and it remains so even after reset() is called.
It is advisable to call #force_encoding or #ext_enc_old= before this is called to set the encoding of the input file.
220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/file_overwrite/file_overwrite.rb', line 220 def encode(*rest, **kwd) enc = (rest[0] || Encoding.default_internal) @int_enc = enc # raises an Exception if called after "completed" return enc if @is_edit_finished || fresh? return @outstr.encode(*rest, **kwd) if @outstr if @outary @outary.map!{|i| i.encode(*rest, **kwd)} return enc end raise 'Should not happen. Contact the code developer.' end |
#end_with?(*rest) ⇒ String
True if the (current) content to supercede the input file end with the specified.
Wrapper of String#end_with?
238 239 240 |
# File 'lib/file_overwrite/file_overwrite.rb', line 238 def end_with?(*rest) dump.end_with?(*rest) end |
#force_encoding(enc) ⇒ Encoding
Implement String#force_encoding
Once this is called, @ext_enc_old is overwritten (or set), and it remains so even after reset() is called.
250 251 252 253 254 255 256 257 258 259 |
# File 'lib/file_overwrite/file_overwrite.rb', line 250 def force_encoding(enc) @ext_enc_old = enc # raises an Exception if called after "completed" return enc if @is_edit_finished || fresh? return @outstr.force_encoding(enc) if @outstr if @outary @outary.map!{|i| i.force_encoding(enc)} return enc end raise 'Should not happen. Contact the code developer.' end |
#fresh? ⇒ Boolean Also known as: reset?
Returns true if the process has not yet started.
263 264 265 |
# File 'lib/file_overwrite/file_overwrite.rb', line 263 def fresh? !state end |
#gsub(*rest, max: 0, **kwd) { ... } ⇒ self
Disclaimer When a block is not given but arguments only (and not expecting Enumerator to return), this method simply calls String#gsub . However, when only 1 argument and a block is given, this method must iterate on its own, which is implemented. I am not 100% confident if this method works in the completely same way as String#gsub in every single situation (except the local variables like $1, $2, etc are not on the #gsub context; see #sub), given the regular expression has so many possibilities; I have made the best effort and so far I have not found any cases where this method breaks. This method is more inefficient and slower than the original String#gsub as this method scans/matches the string twice as many times as String#gsub (which is unavoidable to implement it properly, I think), and the implementation is in pure Ruby.
Similar to String#gsub
This method can be chained. This method never returns an Enumerator.
This method supplies the MatchData of the match as the second block parameter in addition to the matched string as in String#sub.
Being different from the standard Srrint#gsub, this method accepts the optional parameter max, which specifies the maximum number of times of the matches and is valid ONLY WHEN a block is given.
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 |
# File 'lib/file_overwrite/file_overwrite.rb', line 723 def gsub(*rest, max: 0, **kwd, &bloc) return sub(*rest, max: 1, **kwd, &bloc) if 1 == max # Note: Error message would be labelled as 'sub' return self if sub_gsub_args_only(*rest, max: max, **kwd) if !block_given? raise ArgumentError, full_method_name+' does not support the format to return an enumerator.' end max = 5.0/0 if max.to_i <= 0 scans = @outstr.scan(rest[0]) return self if scans.empty? # no matches scans.map!{|i| [i].flatten} # Originally, it can be a double array. regbase_str = rest[0].to_s prematch = '' ret = '' imatch = 0 # Number of matches begin scans.each do |ea_sc| str_matched = ea_sc[0] imatch += 1 pre_size = prematch.size pos_end_p1 = @outstr.index(str_matched, pre_size) # End+1 str_between = @outstr[pre_size...pos_end_p1] prematch << str_between ret << str_between regex = Regexp.new( sprintf('(?<=\A%s)%s', Regexp.quote(prematch), regbase_str) ) #regex = rest[0] if prematch.empty? # The first run m = regex.match(@outstr) prematch << str_matched # Not to break the specification of sub(), but just to extend. ret << yield(m[0], m).to_s break if imatch >= max end ret << Regexp.last_match.post_match # Guaranteed to be non-nil. @outstr = ret return self rescue NoMethodError => err warn_for_sub_gsub(err) raise end end |
#gsub!(*rest, **kwd) { ... } ⇒ self
773 774 775 |
# File 'lib/file_overwrite/file_overwrite.rb', line 773 def gsub!(*rest, **kwd, &bloc) gsub(*rest, &bloc).run!(**kwd) end |
#modify(**kwd) {|ioin, @iotmp| ... } ⇒ self Also known as: open
Modify the content in the block (though not committed, yet)
Two parameters are passed to the block: io_r and io_w. The former is the read-descriptor to read from the original file and the latter is the write-descriptor to write whatever to the temporary file, which is later moved back to the original file when you #run!.
Note the IO pointer for the input file is reset after this method. Hence, chaining this method makes no effect (warning is issued), but only the last one is taken into account.
If you want to halt, undo and reset your modification process in the middle, issue
raise FileOverwriteError [Your_Message]
and it will be rescued. Your_Message is printed to STDERR if verbose was specified in #initialize or $DEBUG
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
# File 'lib/file_overwrite/file_overwrite.rb', line 458 def modify(**kwd) raise ArgumentError, 'Block must be given.' if !block_given? normalize_status(:@is_edit_finished) kwd_def = {} kwd_def[:ext_enc] = @ext_enc_old if @ext_enc_old kwd_def[:int_enc] = @int_enc if @int_enc kwd = kwd_def.merge kwd begin File.open(@fname, **kwd) { |ioin| @iotmp = tempfile_io yield(ioin, @iotmp) } rescue FileOverwriteError => err warn err. if @verbose reset end self end |
#modify!(**kwd) {|ioin, @iotmp| ... } ⇒ self Also known as: open!
488 489 490 |
# File 'lib/file_overwrite/file_overwrite.rb', line 488 def modify!(**kwd, &bloc) modify(&bloc).run!(**kwd) end |
#read(**kwd) {|str| ... } ⇒ self
Handler to process the entire string of the file (or current content)
If block is not given, just sets the state as String
Else, File.read(infile) is given to the block. Then, the returned value is held as a String, hence this method can be chained. If the block returns nil (or Boolean), FileOverwriteError is raised. Make sure to return a String (whether an empty string or “true”)
Note this method does not take arguments as in IO.read
594 595 596 597 598 599 600 601 602 603 604 |
# File 'lib/file_overwrite/file_overwrite.rb', line 594 def read(**kwd, &bloc) if :first == normalize_status(:@outstr) adjust_input_encoding(**kwd){ |f| # @fname @outstr = File.read f } end @outstr = yield(@outstr) if block_given? raise FileOverwriteError, 'ERROR: The returned value from the block in read() can not be nil or Boolean.' if !@outstr || true == @outstr self end |
#read!(**kwd) { ... } ⇒ self
612 613 614 |
# File 'lib/file_overwrite/file_overwrite.rb', line 612 def read!(**kwd, &bloc) read(**kwd, &bloc).run!(**kwd) end |
#readlines(*rest, **kwd) {|str| ... } ⇒ self
Takes a block in which the entire String of the file is passed.
IO.readlines(infile) is given to the block, where Encode may be taken into account if specified already.
The block must return an Array, the number of the elements of which can be allowed to differ from the input. The elements of the Array will be joined to output to the overwritten file in the end.
512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'lib/file_overwrite/file_overwrite.rb', line 512 def readlines(*rest, **kwd, &bloc) raise ArgumentError, 'Block must be given.' if !block_given? if :first == normalize_status(:@outary) adjust_input_encoding(**kwd){ |f| # @fname @outary = IO.readlines(f, *rest) } end @outary = yield(@outary) self end |
#ready? ⇒ Boolean
Returns true if the instance is ready to run (to execute overwriting the file).
270 271 272 |
# File 'lib/file_overwrite/file_overwrite.rb', line 270 def ready? !fresh? && !completed? end |
#replace_with(str) ⇒ self
Similar to String#replace but the original is not modified
This method can be chained.
623 624 625 626 627 |
# File 'lib/file_overwrite/file_overwrite.rb', line 623 def replace_with(str) read @outstr = str.to_s self end |
#replace_with!(str, **kwd) { ... } ⇒ self
Alias to self.#replace_with.#run!
634 635 636 |
# File 'lib/file_overwrite/file_overwrite.rb', line 634 def replace_with!(str, **kwd) replace_with(str).run!(**kwd) end |
#reset ⇒ NilClass
Reset all the modification which is to be applied
279 280 281 282 283 284 285 286 |
# File 'lib/file_overwrite/file_overwrite.rb', line 279 def reset @outstr = nil @outary = nil @is_edit_finished = nil close_iotmp # @iotmp=nil; immediate deletion of the temporary file warn "The modification process is reset." if $DEBUG nil end |
#run!(backup: @backup, suffix: @suffix, noop: @noop, verbose: @verbose, clobber: @clobber, touch: @touch, setsize: true, **kwd) ⇒ NilClass, self Also known as: run
Actually performs the file modification
If setsize option is true (Default) or verbose, method #sizes is activated after this method, which returns a hash of file sizes in bytes before and after, so you can chain it. Note this method returns nil if the input file is not opened at all.
The folloing optional parameters are taken into account. Any other options are ignored.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/file_overwrite/file_overwrite.rb', line 383 def run!(backup: @backup, suffix: @suffix, noop: @noop, verbose: @verbose, clobber: @clobber, touch: @touch, setsize: true, **kwd) raise FileOverwriteError, 'The process has been already completed.' if completed? bkupname = get_bkupname(backup, suffix, noop, verbose, clobber) sizes = write_new(verbose, setsize) return nil if !sizes return self if run_identical?(noop, verbose, touch) if bkupname msg4bkup = ", Backup: " + bkupname if verbose else io2del = tempfile_io io2delname = io2del.path end fname_to = (bkupname || io2delname) mv( @fname, fname_to, noop: noop, verbose: $DEBUG) # defined in FileUtils begin mv(@iotmp.path, @fname, noop: noop, verbose: $DEBUG) # defined in FileUtils rescue msg = sprintf("Process halted! File system error in renaming the temporary file %s back to the original %s", @iotmp.path, @fname) warn msg raise end # @iotmp.close(true) # to immediate delete the temporary file # If commented out, GC looks after it. File.unlink io2delname if io2delname && !noop # if noop, GC will delete it. if verbose msg = sprintf("%sFile %s updated (Size: %d => %d bytes%s)\n", prefix(noop), @fname, sizes[:old], sizes[:new], msg4bkup) msg end @is_completed = true self.freeze return self end |
#state ⇒ Class, ...
Returns the current state
nil if no modification has been attempted. IO if the modification has been made and it is wating to run. String or Array (or their equivalent), depending how it has been chained so far. true if the process has been completed.
307 308 309 310 311 312 313 |
# File 'lib/file_overwrite/file_overwrite.rb', line 307 def state return true if completed? return IO if @is_edit_finished return @outstr.class if @outstr return @outary.class if @outary nil end |
#sub(*rest, max: 1, **kwd) { ... } ⇒ self
Similar to String#sub
This method can be chained. This method never returns an Enumerator.
WARNING: Do not use the local variables like $1, $2, $‘, and Regexp.last_match inside the block supplied. They would NOT be interpreted in the context of this method, but that in the caller, which is most likely not to be what you want.
Instead, this method supplies the MatchData of the match as the second block parameter in addition to the matched string as in String#sub.
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 |
# File 'lib/file_overwrite/file_overwrite.rb', line 656 def sub(*rest, max: 1, **kwd, &bloc) return self if sub_gsub_args_only(*rest, max: max, **kwd) if !block_given? raise ArgumentError, full_method_name+' does not support the format to return an enumerator.' end if max.to_i != 1 return gsub(*rest, max: max, **kwd, &bloc) end begin m = rest[0].match(@outstr) # Returning nil, Integer etc is accepted in the block of sub/gsub @outstr = m.pre_match + yield(m[0], m).to_s + m.post_match if m # Not to break the specification of sub(), but just to extend. return self rescue NoMethodError => err warn_for_sub_gsub(err) raise end end |
#sub!(*rest, **kwd) { ... } ⇒ self
686 687 688 |
# File 'lib/file_overwrite/file_overwrite.rb', line 686 def sub!(*rest, **kwd, &bloc) sub(*rest, &bloc).run!(**kwd) end |
#temporary_filename ⇒ String, NilClass
Returns the temporary filename (or nil), maybe for debugging
It may not be open?
294 295 296 |
# File 'lib/file_overwrite/file_overwrite.rb', line 294 def temporary_filename @iotmp ? @iotmp.path : nil end |
#tr(*rest, **kwd) ⇒ self
Similar to String#tr
This method can be chained.
785 786 787 788 789 |
# File 'lib/file_overwrite/file_overwrite.rb', line 785 def tr(*rest, **kwd) read(**kwd){ |outstr| outstr.tr!(*rest) || outstr } end |
#tr!(*rest, **kwd) ⇒ self
794 795 796 |
# File 'lib/file_overwrite/file_overwrite.rb', line 794 def tr!(*rest, **kwd) tr(*rest, **kwd).run!(**kwd) end |
#tr_s(*rest, **kwd) ⇒ self
Similar to String#tr_s
This method can be chained.
805 806 807 808 809 |
# File 'lib/file_overwrite/file_overwrite.rb', line 805 def tr_s(*rest, **kwd) read(**kwd){ |outstr| outstr.tr_s!(*rest) || outstr } end |
#tr_s!(*rest, **kwd) ⇒ self
814 815 816 |
# File 'lib/file_overwrite/file_overwrite.rb', line 814 def tr_s!(*rest, **kwd) tr_s(*rest, **kwd).run!(**kwd) end |
#valid_encoding? ⇒ Boolean, NilClass
String#valid_encoding?()
returns nil if the process has been already completed.
320 321 322 323 |
# File 'lib/file_overwrite/file_overwrite.rb', line 320 def valid_encoding?() return nil if completed? dump.valid_encoding? end |