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

B

Berger, Daniel

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
 
A

Austin Ziegler

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.
=20
1: puts "Hello World"
2: foo()
3: puts "How's it going?"
=20
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.
=20
Any ideas?

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

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

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

-austin
--=20
Austin Ziegler * (e-mail address removed)
* Alternate: (e-mail address removed)
 
B

Brian Schröder

Hi all,
=20
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.
=20
For example:
=20
1: puts "Hello World"
2: foo()
3: puts "How's it going?"
=20
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.
=20
Any ideas?
=20
Regards,
=20
Dan
=20
=20
=20
=20
=20
Hello Dan,

maybe something like this:

bschroed@black:~/svn/projekte/ruby-things$ cat slurpself.rb=20
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=20
Hello World
["puts \"How's it going?\"\n", "puts \"Just fine\"\n"]
How's it going?
Just fine

regards,

Brian

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

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

Ezra Zygmuntowicz

Hi all,


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

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\""]}
------------
["./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
(e-mail address removed)
 
D

daz

Daniel said:
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
 
A

Ara.T.Howard

Hi all,

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


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
---
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
===============================================================================
 
A

Austin Ziegler

Daniel said:
From within a Ruby program, is there a way to get Ruby to re-read itsel= f
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 !
=20
# Line 1
DATA.rewind
script =3D DATA.readlines
p script[1..2]
__END__
=20
#-> ["DATA.rewind\n", "script =3D DATA.readlines\n"]

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
--=20
Austin Ziegler * (e-mail address removed)
* Alternate: (e-mail address removed)
 
D

daz

Austin said:
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
 
A

Austin Ziegler

You just requoted Dan's original question:
"re-read itself"

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
--=20
Austin Ziegler * (e-mail address removed)
* Alternate: (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top