The attached minimal gem contains a script that reads “Hello World!”
from its DATA section and then prints it.
The script works, but after installing (sudo gem install
datasection.gemspec), the wrapper in /usr/local/bin does not see the
DATA section:
$ datasection
/usr/local/lib/ruby/gems/1.9.1/gems/datasection-0.01/bin/datasection:2:in
<top (required)>': uninitialized constant DATA (NameError) from /usr/local/bin/datasection:19:in
load’
from /usr/local/bin/datasection:19:in `’
In my actual script the DATA section is planned to contain a much larger
erb-template and it seems not very elegant to put those as strings in
the script.
DATA points to the contents after the END directive of the
executable
script that acts as an entry point (is not per file).
RubyGems wraps gem’s executables with its own executables. Those
wrappers
know where’s the gem executable located, and also understand version
selection as an underscored argument. So, in a gem, the very gem’s
executables are not the main files because of this indirection.
On 2012-04-23 11:39, Xavier N. wrote:
DATA points to the contents after the END directive of the
executable script that acts as an entry point (is not per file).
RubyGems wraps gem’s executables with its own executables. Those
wrappers know where’s the gem executable located, and also understand
version selection as an underscored argument. So, in a gem, the very
gem’s executables are not the main files because of this indirection.
That’s clear, but does that mean there’s no workaround?
Can Ruby not be told that the DATA section is somewhere else?
On Mon, Apr 23, 2012 at 1:49 PM, Wybo D. [email protected] wrote:
That’s clear, but does that mean there’s no workaround?
Can Ruby not be told that the DATA section is somewhere else?
There’s no workaround related to the DATA constant itself, it’s defined
only for the main file.
You could of course switch to regular Ruby, for example throwing at the
end
of the script:
BEGIN {
require 'stringio'
DATA = StringIO.new(<<EOS)
...
EOS
}
That’d work because the main file is not going to define DATA (RubyGems
does not generate END), so the constant is undefined. You could also
scan FILE in a BEGIN block looking for END by hand to fully
emulate
the feature.
The BEGIN block is needed because in the original DATA feature you get
the
constant defined in the top-level right away if END is present.
Well just giving some ideas, the main point is that you need to do it in
Ruby.
On Mon, Apr 23, 2012 at 3:55 PM, Xavier N. [email protected] wrote:
BEGIN {
require 'stringio'
DATA = StringIO.new(<<EOS)
...
EOS
}
Ah, the (unquoted) indentation is wrong in that heredoc, but you see the
idea.
no one knows how we can do it. (:
Please can some one show me how to stop getting emails from
[email protected]
On Mon, Apr 23, 2012 at 11:37 AM, Ender Ahmet Y. [email protected]
wrote:
no one knows how we can do it. (:
What do you mean? The instructions are right here:
http://www.ruby-lang.org/en/community/mailing-lists/
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 23/04/2012 16:37, Ender Ahmet Y. wrote:
no one knows how we can do it. (:
On Mon, Apr 23, 2012 at 6:29 PM, Billy Alcazar <[email protected]
mailto:[email protected]> wrote:
Please can some one show me how to stop getting emails from
[email protected] <mailto:[email protected]>
In the headers of every email you receive is:
List-Unsubscribe: mailto:[email protected]?body=unsubscribe
Try that. Or, alternatively, go to Google groups & unsubscribe there.
Cheers,
Phil…
But masters, remember that I am an ass.
Though it be not written down,
yet forget not that I am an ass.
Wm. Shakespeare - Much Ado About Nothing
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: §auto-key-locate cert pka ldap hkp://keys.gnupg.net
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iQEcBAEBAgAGBQJPlXhJAAoJEKpMeDHWT5ADGwIIAItSzGGBZ4dVd6PdFPErc6Mo
X0cGyG0Ze2/XjYPUKEnm/g5+IhsSchuccKrvtTAoRo/+HYVStb4xmWNQxleyN1R5
AiLOW8BJHIpHrbKIUsLSqeklwLbXkaTdNbA2JFQOHbUtWdly9vS0J3r9HH9xjpVG
f4aJNgiE+4uvsZK9VxEBFR5pREvNgJWW+Wt63vlOS+zL4svfmwhlsRBLqN4SGAq6
bhX1N7QAWJms43F7mw9pMVat8OE8wHwKyY26XihpQT75UbPv4i4h5UarUoHfJW8B
UJw6onWcu9z0t8aE6fX8sa/QmVMoSYi+g3/imrOqcM+67tTERiLpc0Fx+BXRGUQ=
=hwGK
-----END PGP SIGNATURE-----
On Apr 23, 2012, at 04:49 , Wybo D. wrote:
That’s clear, but does that mean there’s no workaround?
Can Ruby not be told that the DATA section is somewhere else?
This is my ((slightly?) horrible) workaround:
data = File.read(FILE).split(/END/).last
Ryan D. писал 23.04.2012 22:58:
On Apr 23, 2012, at 04:49 , Wybo D. wrote:
That’s clear, but does that mean there’s no workaround?
Can Ruby not be told that the DATA section is somewhere else?
This is my ((slightly?) horrible) workaround:
data = File.read(FILE).split(/END/).last
This is better:
data = File.read(FILE).split(/END/, 2).last
1.9.3p125 :001 > “a,b,c”.split(",", 2)
=> [“a”, “b,c”]
1.9.3p125 :002 > “a,b,c”.split(",")
=> [“a”, “b”, “c”]
I you don’t need the BEGIN block nor constants, I think you could just
use some ordirary heredocs or some other conventional Ruby idiom.
Sent from my iPhone
On 2012-04-24 10:53, Xavier N. wrote:
I you don’t need the BEGIN block nor constants, I think you could just use some
ordirary heredocs or some other conventional Ruby idiom.
sure, but as said in my initial mail, it’s not very elegant to clog a
script with large blocks of erb templates…
On 2012-04-23 22:57, Peter Z. wrote:
This is better:
data = File.read(FILE).split(/END/, 2).last
That’s great, thanks Peter, Ryan.
But it needs a correction, because the script is now also split on the
END in the “data =…” line itself, so it needs a ^:
data = File.read(FILE).split(/^END/, 2).last
And Ryan’s ,2 can be skipped if one wants more than one subsection in
the DATA section. Here’s my test script, including the idea of using it
for erb templates:
#!/usr/bin/env ruby
require ‘optparse’
require ‘erb’
name = ‘Unknown’
OptionParser.new do |opt|
opt.on(’-n’,’–name=STRING’,String,
‘set the name’
) do |v| name = v end
end.parse!
data1,data2 = File.read(FILE).
split(/^END/)[1…-1].
map { |x| ERB.new(x).result(binding) }
puts ‘’,“data1: #{data1}”, ‘’,“data2: #{data2}”
END
Hello <%= name %>
This is data 1, two lines.
END
This is data 2,
3 lines,
including this one.
On Tue, Apr 24, 2012 at 11:01 AM, Wybo D. [email protected] wrote:
On 2012-04-24 10:53, Xavier N. wrote:
I you don’t need the BEGIN block nor constants, I think you could just use some
ordirary heredocs or some other conventional Ruby idiom.
sure, but as said in my initial mail, it’s not very elegant to clog a
script with large blocks of erb templates…
I agree to Xavier, it’s not such a big difference. Just do
single quotes are important!
MY_DATA = <<‘DAT’
doc is here
DAT
And if you place it at the end of the script you have pretty much the
same as with END - plus, you can even define more documents that
way. You could also do
MY_DATA = %q{
doc is here
}
MY_DATA = %q[
doc is here
]
etc.
Kind regards
robert
On 2012-04-24 11:08, Robert K. wrote:
single quotes are important!
MY_DATA = <<‘DAT’
doc is here
DAT
And if you place it at the end of the script you have pretty much the
same as with END - plus, you can even define more documents that
way. You could also do
Maybe I don’t see the clue, but putting the doc at the end of the script
(and thus necessarily using it before its definition) results in:
uninitialized constant MY_DATA (NameError)
On Tue, Apr 24, 2012 at 2:59 PM, Wybo D. [email protected] wrote:
Maybe I don’t see the clue, but putting the doc at the end of the script
(and thus necessarily using it before its definition) results in:
uninitialized constant MY_DATA (NameError)
Putting it at the end does not necessarily mean you use it before the
definition especially if the file is a library file (i.e. no code gets
executed).
$ ruby19 y.rb
3
$ cat -n y.rb
1
2
3 require ‘./x’
4
5 puts size()
6
$ cat -n x.rb
1
2
3 def size
4 return MY_DATA.length
5 end
6
7
8 MY_DATA = “foo”
9
I cannot judge your case since your demo gem just contained demo
content. If you insist on having the data at the end, there are other
approaches as well:
$ ruby19 -r ./z.rb -e ‘p get’
“This is\nmy\n\ndata\n”
rklemme@padrklemme2 /tmp/tmpenv.sh-8oDIBS
$ cat -n z.rb
1
2
3 def get
4
File.read(FILE)[%r{^=begi\s*#\sDATA$\r?\n(.)^=end\s*\z}m, 1]
5 end
6
7 =begin # DATA
8 This is
9 my
10
11 data
12 =end
Kind regards
rober
On 2012-04-24 15:28, Xavier N. wrote:
Did you receive my reply (I think it was the first one in the thread?)
with the BEGIN blocks? Do you know what is a BEGIN block?
yes, but I didn’t well understand it - now I see what you meant:
#!/usr/bin/env ruby
require ‘optparse’
name = ‘Unknown’
OptionParser.new do |opt|
opt.on(’-n’,’–name=STRING’,String,
‘set the name’
) do |v| name = v end
end.parse!
puts ‘’,“data1: #{DATA1.result(binding)}”,
‘’,“data2: #{DATA2.result(binding)}”
TEMPLATES
BEGIN {
require ‘erb’
DATA1 = ERB.new(<<-‘DAT’)
Hello <%= name %>
This is data 1, two lines.
DAT
DATA2 = ERB.new(<<-‘DAT’)
This is data 2,
3 lines,
including this one.
DAT
}
Exactly! Given that END is not per file, I think that solution is a
good compromise. It allows you to put this auxiliary stuff down the
script,
and at the same time have it available in the main code.
One could invert the order and put the templates first, but I understand
your desire to put them down. That is, if END was per file, we’d use
it
for this case.
On Tue, Apr 24, 2012 at 2:59 PM, Wybo D. [email protected] wrote:
Maybe I don’t see the clue, but putting the doc at the end of the script
(and thus necessarily using it before its definition) results in:
uninitialized constant MY_DATA (NameError)
Did you receive my reply (I think it was the first one in the thread?)
with
the BEGIN blocks? Do you know what is a BEGIN block?