Passing binding or arguments to ERB from the command line
If you are using unix, try following:
$ cat 1.erb
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
$ (echo '<% name="Joe"; quality="fantastic" %>' && cat 1.erb) | erb
Hello. My name is Joe. I hope your day is fantastic.
Can I pass variables to be rendered by erb from the command line?
As of Ruby 2.2 you can set local variables in Erb from the command line.
You would need to change your code to use local variables rather than instance variables. For example if you had (stripped down from your code):
<VirtualHost <%= http_host %>:<%= http_port %>>
You could then call it with:
$ erb http_host=http://example.com http_port=1234 my_file.erb
and the result would be:
<VirtualHost http://example.com:1234>
How to pass binding with ERB.result_with_hash
In your case, if you need to use both the args
and binding
, you need to populate keys/values of your args
into the binding object.
# To avoid polluting your current binding, copy to a new one
b_clone = binding.clone
args.each { |k, v| b_clone.local_variable_set(k,v) }
ERB.new(template).result(b_clone)
So you can use both methods in your binding and keys/values in args as variables
Ruby templates: How to pass variables into inlined ERB?
Got it!
I create a bindings class
class BindMe
def initialize(key,val)
@key=key
@val=val
end
def get_binding
return binding()
end
end
and pass an instance to ERB
dataHash.keys.each do |current|
key = current.to_s
val = dataHash[key]
# here, I pass the bindings instance to ERB
bindMe = BindMe.new(key,val)
result = template.result(bindMe.get_binding)
# unnecessary code goes here
end
The .erb template file looks like this:
Key: <%= @key %>
How do I execute ruby template files (ERB) without a web server from command line?
You should have everything you need in your ruby/bin directory. On my (WinXP, Ruby 1.8.6) system, I have ruby/bin/erb.bat
erb.bat [switches] [inputfile]
-x print ruby script
-n print ruby script with line number
-v enable verbose mode
-d set $DEBUG to true
-r [library] load a library
-K [kcode] specify KANJI code-set
-S [safe_level] set $SAFE (0..4)
-T [trim_mode] specify trim_mode (0..2, -)
-P ignore lines which start with "%"
so erb your_erb_file.erb
should write the result to STDOUT.
(EDIT: windows has erb.bat and just plain "erb". The .bat file is just a wrapper for erb, which I guess should make the same command work pretty much the same on any OS)
See the prag prog book discussion (starts about half-way down the page).
Note also that Jack Herrington wrote a whole book about code generation that uses Ruby/ERB.
how to use erb to output file after binding
Note that ERB isn't printing this - you are.
print erb.result( binding )
Let's change that. We'll open the file handle, in w
mode to write, and write the ERB result to the file.
File.open('text2.txt', 'w') do |f|
f.write erb.result(binding)
end
File.open('text2.txt', 'w')
opens the file text2.txt
in w
rite mode, and passes that file object into the block. f.write
outputs its argument to the file. In some cases you might need to call f.close
to allow other processes on your computer to access the file, but since we used the block notation here instead, the file is closed automatically at the end of the block.
Code untested - let me know if you get an error. Good luck on your coding journey!
Passing multiple pieces of data via command line to be separately evaluated using ARGV
If I properly understood what you want to do:
ARGV.each_slice(3) { |a1, a2, a3|
# NB: a2 and/or a3 may be nil here if ARGV.size % 3 ≠ 0
puts "#{a1}×#{a2}×#{a3}"
}
puts "Init NOW"
Yielding:
~ ruby a.rb arg1 arg2 arg3 arg4 arg5 arg6 arg7
# arg1×arg2×arg3
# arg4×arg5×arg6
# arg7××
# Init NOW
UPD
After a clarification of the task:
class Operator
attr_accessor :a1, :a2, :a3, :a4
def initialize attrs
@a1, @a2, @a3, @a4 = attrs
end
def begin
puts "[BEGIN] ⇒ 1: #{@a1}, 2: #{@a2}, 3: #{@a3}"
end
def add
puts "[ADD] ⇒ 1: #{@a1}, 2: #{@a2}, 3: #{@a3}, 4: #{@a4}"
end
def subtract
puts "[SUBTR] ⇒ 1: #{@a1}, 2: #{@a2}, 3: #{@a3}, 4: #{@a4}"
end
end
meth, *args = ARGV
Operator.new(args).send (meth.to_sym)
Which gives:
~ ruby a.rb add arg1 arg2 arg3 arg4
# [ADD] ⇒ 1: arg1, 2: arg2, 3: arg3, 4: arg4
~ ruby a.rb begin arg1 arg2 arg3
# [BEGIN] ⇒ 1: arg1, 2: arg2, 3: arg3
ERB partials to create static html with command line
What about this script:
require 'erb'
def render(filename)
ERB.new(File.read "#{filename}.html.erb").result(binding)
end
File.open('new-test.html', 'w') do |file|
file.write render('test')
end
It will read your test.html.erb, interpolate the ruby code properly including the calls to our custom render (so no need for any external library to handle that), and output a new-test.html file. You can run it by:
ruby script_name.rb
Notice how we need to provide a binding object to ERB. It is what defines the context of evaluation of the interpolated ruby in the template. Here we are providing the binding of the script itself, that's why we have access to the render method inside the erb template.
Ruby - Automatically pass binding() to method like eval?
Okay, so it turns out there's no easy answer. I've compiled a list here:
Ruby: Binding of Caller Solutions
And it breaks down to the following possibilities (expanded on in the link above):
- Use binding_of_caller gem
- Use a really sneaky pure ruby trick that only works if your method takes no args (involving define_singleton_method and then composing (>>) Object::method(:binding) with your method). See examples at https://bugs.ruby-lang.org/issues/18487
- Use TracePoint API for a pure ruby solution that is amazingly slow
- Call rb_eval_string_protect("binding") inside of a C extension which, until Ruby 3.2.0, will get you all of the binding (but with a corrupted receiver)
- Use my cut down C extension that takes the important bits out of the gem that binding_of_caller depends upon (debug_inspector)
Related Topics
Rspec: How to Write a Test That Expects Certain Output But Doesn't Care About the Method
Trying to Understand Use of Self.Method_Name VS. Classname.Method_Name in Ruby
Best Way to Handle Data Attributes in Slim
Stubbing Chained Methods with Rspec
How to Return Correct Http Error Codes from Ruby on Rails Application
How to Pass an Argument When Calling a View File
What Is Purpose of Around_Create Callback in Rails Model
Is a Global Variable Defined Inside a Sinatra Route Shared Between Requests
Rails Two-Legged Oauth Provider
How to Catch All Http Traffic (Local Proxy)
How to Integrate Hoptoad with Delayedjob and Daemonspawn
Ruby on Rails with Imap Idle for Multiple Accounts
Why Does Ruby Use Respond_To? Instead of Responds_To
Rspec: How to Write a Test That Expects Certain Output But Doesn't Care About the Method