Re-reading a portion of a source file from a specific point

(Berger, Daniel) #1

Hi all,

From within a Ruby program, is there a way to get Ruby to re-read itself
from a specific part of the file? Let me explain. Say I have a method
"foo". I would like "foo" to slurp the rest of the script into memory
and write it to a file, possibly a temp file.

For example:

1: puts "Hello World"
2: foo()
3: puts "How's it going?"

In this script I would like lines 2 and 3 (or possibly just line 3 - I'm
not sure yet), but NOT line 1, read into memory and written to a file
(by the foo method). I thought perhaps there were some tricks I could
use with __DATA__, __END__ or __FILE__, but I wasn't sure.

Any ideas?

Regards,

Dan

(Austin Ziegler) #2

Parse #caller[0]? Use __FILE__ and __LINE__?

  def foo
    c0 = caller[0].match(/^(.+):(\d+)(?::in `.*)?$/)
    c0 = c0.captures if c0
    data = File.open(c0[0], "rb") { |f| f.read }
    data = data.split($/)
    data = data[(c0[1].to_i -1) .. -1]
    p data
  end
  def bar
    foo
  end

  puts "Hello, world."
  foo
  bar
  puts "Goodbye, world."

-austin

···

On 8/9/05, Berger, Daniel <Daniel.Berger@qwest.com> wrote:

From within a Ruby program, is there a way to get Ruby to re-read itself from
a specific part of the file? Let me explain. Say I have a method "foo". I
would like "foo" to slurp the rest of the script into memory and write it to
a file, possibly a temp file.

1: puts "Hello World"
2: foo()
3: puts "How's it going?"

In this script I would like lines 2 and 3 (or possibly just line 3 - I'm not
sure yet), but NOT line 1, read into memory and written to a file (by the foo
method). I thought perhaps there were some tricks I could use with __DATA__,
__END__ or __FILE__, but I wasn't sure.

Any ideas?

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

(Brian Schröder) #3

Hello Dan,

maybe something like this:

bschroed@black:~/svn/projekte/ruby-things$ cat slurpself.rb
def tail_from(file, line)
  File.readlines(file)[line..-1]
end

puts "Hello World"
p tail_from(__FILE__, __LINE__)
puts "How's it going?"
puts "Just fine"
bschroed@black:~/svn/projekte/ruby-things$ ruby slurpself.rb
Hello World
["puts \"How's it going?\"\n", "puts \"Just fine\"\n"]
How's it going?
Just fine

regards,

Brian

···

On 09/08/05, Berger, Daniel <Daniel.Berger@qwest.com> wrote:

Hi all,

From within a Ruby program, is there a way to get Ruby to re-read itself
from a specific part of the file? Let me explain. Say I have a method
"foo". I would like "foo" to slurp the rest of the script into memory
and write it to a file, possibly a temp file.

For example:

1: puts "Hello World"
2: foo()
3: puts "How's it going?"

In this script I would like lines 2 and 3 (or possibly just line 3 - I'm
not sure yet), but NOT line 1, read into memory and written to a file
(by the foo method). I thought perhaps there were some tricks I could
use with __DATA__, __END__ or __FILE__, but I wasn't sure.

Any ideas?

Regards,

Dan

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

(Ezra Zygmuntowicz) #4

There is an obscure constant called SCRIPT_LINES__ . To use it you would have to put the script that you want to have access to in a file and include it in another. Like so:

-----test.rb--------
a= "Hello World"
b = "Foo Bar"
c = "How's it going?"
d = "Another Line"
------end test.rb------

------main.rb-------
SCRIPT_LINES__ = {}
require 'test'
p SCRIPT_LINES__
p SCRIPT_LINES__.keys
-----end main.rb--------

Result:
ezra:~/Sites ez$ ruby main.rb
{"./main.rb"=>["a= \"Hello World\"\n", "b = \"Foo Bar\"\n", "c = \"How's it going?\"\n", "d = \"Another Line\""]}

···

On Aug 9, 2005, at 8:14 AM, Berger, Daniel wrote:

Hi all,

From within a Ruby program, is there a way to get Ruby to re-read itself

from a specific part of the file? Let me explain. Say I have a method
"foo". I would like "foo" to slurp the rest of the script into memory
and write it to a file, possibly a temp file.

For example:

1: puts "Hello World"
2: foo()
3: puts "How's it going?"

In this script I would like lines 2 and 3 (or possibly just line 3 - I'm
not sure yet), but NOT line 1, read into memory and written to a file
(by the foo method). I thought perhaps there were some tricks I could
use with __DATA__, __END__ or __FILE__, but I wasn't sure.

Any ideas?

Regards,

Dan

------------
["./main.rb"]

     So after you do this, you will have a hash that contains arrays of every line in every file you require, keyed by the file name of the required file. Kind of wierd but I think you could use this to do what you want to do.

HTH-
-Ezra Zygmuntowicz
Yakima Herald-Republic
WebMaster
509-577-7732
ezra@yakima-herald.com

(daz) #5

Daniel Berger wrote:

From within a Ruby program, is there a way to get Ruby to re-read itself
from a specific part of the file?
[...]
I thought perhaps there were some tricks I could
use with __DATA__, __END__ or __FILE__, but I wasn't sure.

The DATA constant initially points after the __END__ marker.
The origin of the DATA IO object is the script itself !

# Line 1
DATA.rewind
script = DATA.readlines
p script[1..2]
__END__

#-> ["DATA.rewind\n", "script = DATA.readlines\n"]

daz

(Ara.T.Howard) #6

one approach:

     harp:~ > cat a.rb
     require 'tempfile'
     require 'stringio'

     def record opts = {}
       getopt =
         lambda do |o|
           catch('opt') do
             [o, o.to_s, o.to_s.intern].each{|k| throw 'opt', opts[k] if opts.has_key? k}
             throw 'opt', nil
           end
         end
       file = getopt['file'] or raise ArgumentError, 'no file'
       a = getopt['start'] or raise ArgumentError, 'no start'
       b = getopt['end'] || -1
       into = getopt['into'] || Tempfile::new(File::basename(file))
       into << IO::readlines(file)[a .. b].join
       into.flush if into.respond_to?('flush')
       into.rewind if into.respond_to?('rewind')
       into
     end

     puts '---'
     tmp = record 'file' => __FILE__, 'start' => __LINE__
     print tmp.read

     puts '---'
     tmp = record 'file' => __FILE__, 'start' => -2, 'end' => -1, 'into' => StringIO::new
     print tmp.read

     harp:~ > ruby a.rb

···

On Wed, 10 Aug 2005, Berger, Daniel wrote:

Hi all,

From within a Ruby program, is there a way to get Ruby to re-read itself

from a specific part of the file? Let me explain. Say I have a method
"foo". I would like "foo" to slurp the rest of the script into memory
and write it to a file, possibly a temp file.

For example:

1: puts "Hello World"
2: foo()
3: puts "How's it going?"

In this script I would like lines 2 and 3 (or possibly just line 3 - I'm
not sure yet), but NOT line 1, read into memory and written to a file
(by the foo method). I thought perhaps there were some tricks I could
use with __DATA__, __END__ or __FILE__, but I wasn't sure.

Any ideas?

Regards,

Dan

     ---
     print tmp.read

     puts '---'
     tmp = record 'file' => __FILE__, 'start' => -2, 'end' => -1, 'into' => StringIO::new
     print tmp.read
     ---
     tmp = record 'file' => __FILE__, 'start' => -2, 'end' => -1, 'into' => StringIO::new
     print tmp.read

cheers.

-a
--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

(Austin Ziegler) #7

This only works for the top-level script ($0). It does not work for
included scripts, the way that Perl's __END__ and DATA markers do.

-austin

···

On 8/12/05, daz <dooby@d10.karoo.co.uk> wrote:

Daniel Berger wrote:
> From within a Ruby program, is there a way to get Ruby to re-read itself
> from a specific part of the file?
> [...]
> I thought perhaps there were some tricks I could
> use with __DATA__, __END__ or __FILE__, but I wasn't sure.
The DATA constant initially points after the __END__ marker.
The origin of the DATA IO object is the script itself !

# Line 1
DATA.rewind
script = DATA.readlines
p script[1..2]
__END__

#-> ["DATA.rewind\n", "script = DATA.readlines\n"]

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

(daz) #8

Austin Ziegler wrote:

···

On 8/12/05, daz wrote:
> Daniel Berger wrote:
> > From within a Ruby program, is there a way to get Ruby to re-read itself
> > from a specific part of the file?

This only works for the top-level script ($0). It does not work for
included scripts, the way that Perl's __END__ and DATA markers do.

You just requoted Dan's original question:

"re-read itself"

daz

(Austin Ziegler) #9

So I did. I meant to quote what you said about using __END__ and DATA.
To elaborate for those who may not have understood what I was saying,
though:.

Consider that Dan's program is "reread.rb". If I do this in "myreread.rb":

  require 'reread'

Then Dan's program will reread from the beginning of "myreread.rb"
($0) and not "reread.rb" if it uses __END__ and DATA.

-austin

···

On 8/12/05, daz <dooby@d10.karoo.co.uk> wrote:

Austin Ziegler wrote:
> On 8/12/05, daz wrote:
> > Daniel Berger wrote:
> > > From within a Ruby program, is there a way to get Ruby to re-read itself
> > > from a specific part of the file?
> This only works for the top-level script ($0). It does not work for
> included scripts, the way that Perl's __END__ and DATA markers do.
You just requoted Dan's original question:
"re-read itself"

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca