I want to store the code will be run inside each_with_index block:
describe '#each_with_index' do
subject { [:a,:b].each_with_index{ block.to_ruby } }
context 'when the block prints v to console' do
let(:block) { '|v| puts v' }
specify { expect { subject }.to output(':a :b').to_stdout }
end
context 'when the block prints i to console' do
let(:block) { '|v,i| puts i' }
specify { expect { subject }.to output('0 1').to_stdout }
end
context 'when the block prints v and i to console' do
let(:block) { '|v,i| puts "#{v} and {i}"' }
specify { expect { subject }.to output(':a and 0 :b and 1').to_stdout }
end
end
I don't need the code stored as a string, it is just a way to show you what I mean. I want to do this with in-block code, pipes, and everything. I've got a feeling we can use Proc.new but the pipes are tripping me up.
Something like:
let(:block) { Proc.new{ |v| puts v } }
subject { [:a,:b].each_with_index { |*args| block.call args } }
Related
I have following code:
def test_callback_interface
with_temp_stdio do |stdin, stdout|
stdin.write("hello\n")
stdin.close
stdout.flush
line = nil
replace_stdio(stdin.path, stdout.path) {
Readline.handler_install("> ", true) { |l| line = l }
6.times { Readline.read_char }
Readline.handler_remove
}
assert_equal("hello", line) <------ FAIL here
assert_equal(true, line.tainted?)
stdout.rewind
assert_equal("> ", stdout.read(2))
assert_equal(1, Readline::HISTORY.length)
assert_equal("hello", Readline::HISTORY[0])
end
assert_equal(true, false)
end
it fails on the line assert_equal("hello", line) saying that the line is nil. However, I'm sure that the callback is called (I verified it by putting raise in there). So I must be missing something fundamental about scopes here. Could someone please enlighten me how to get the value of l to the line variable?
Thanks
EDIT:
How do I call the callback inside handler_install/read_char?
static VALUE readline_callback_ensure(VALUE val) {
free(readline_callback_line);
readline_callback_line = NULL;
return Qnil;
}
static VALUE readline_callback_call(VALUE line) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
rb_funcall(proc, id_call, 1, line);
return Qnil;
}
static void readline_callback_callback(char * line) {
if (readline_callback_add_history && line) {
add_history(line);
}
readline_callback_line = line;
rb_ensure(
readline_callback_call, line ? rb_str_new_cstr(line) : Qnil,
readline_callback_ensure, Qnil
);
}
static VALUE readline_callback_handler_install(int argc, VALUE * argv, VALUE self) {
VALUE tmp, add_hist, block;
char * prompt = NULL;
rb_need_block();
if (rb_scan_args(argc, argv, "02&", &tmp, &add_hist, &block) > 0) {
prompt = RSTRING_PTR(tmp);
}
if (RTEST(add_hist)) {
readline_callback_add_history = true;
} else {
readline_callback_add_history = false;
}
rb_ivar_set(mReadline, read_char_cb_proc, block);
rl_callback_handler_install(prompt, readline_callback_callback);
return Qnil;
}
static VALUE readline_callback_read_char(VALUE self) {
VALUE proc = rb_attr_get(mReadline, read_char_cb_proc);
if (NIL_P(proc)) {
rb_raise(rb_eRuntimeError, "No handler installed.");
}
rl_callback_read_char();
return Qnil;
}
So basically read_char calls rl_callback_read_char (gnu readline function), which on detecting complete line invokes my installed handler readline_callback_callback which invoked stored block supplied by user.
Solved, not an scope issue. GNU Readline calls my code once more with NULL on EOF, complete forgot about that.
I am trying to setup a simple password encryption using mongoid-bcrypt-ruby mongoid and sinatra i am also developing on a windows machine
unfortunately whenever I try to persist a new user i get an error from my User.create!() call saying invalid hash
# gemfile
ruby "2.2.4"
source "http://rubygems.org"
gem "sinatra", require: "sinatra/base"
gem "sinatra-contrib", require: "sinatra/namespace"
gem "rack"
gem "thin"
gem "mongoid"
gem "mongoid-bcrypt-ruby"
user model
class User
include Mongoid::Document
include Mongoid::Timestamps
store_in collection: :users
field :first_name, type: String
field :last_name, type: String
field :email, type: String
field :phone_number, type: String
field :password, type: BCrypt::Password
field :is_active, type: Boolean, default: false
field :is_admin, type: Boolean, default: false
# ....
end
class Routes
# ....
post '/submit' do
User.create!(
first_name: params['first_name'],
last_name: params['last_name'],
email: params['email'],
phone_number: params['phone_number'],
password: params['password']
)
end
end
Trace from Sinatra's error page:
BCrypt::Errors::InvalidHash at /api/v1/new_user
invalid hash
file: password.rb location: initialize line: 60
Full Backtrace from Sinatra's error page:
C:/Ruby22/lib/ruby/gems/2.2.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcrypt/password.rb in initialize
raise Errors::InvalidHash.new("invalid hash")
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-bcrypt-ruby-0.0.2/lib/mongoid/bcrypt/ruby.rb in new
when String then self.new(password)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-bcrypt-ruby-0.0.2/lib/mongoid/bcrypt/ruby.rb in demongoize
when String then self.new(password)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/fields/standard.rb in demongoize
delegate :demongoize, :evolve, :mongoize, to: :type
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/fields.rb in block (2 levels) in create_field_getter
value = field.demongoize(raw)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/validatable.rb in read_attribute_for_validation
send(attr)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in block in validate
value = record.read_attribute_for_validation(attribute)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in each
attributes.each do |attribute|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validator.rb in validate
attributes.each do |attribute|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in public_send
filter.public_send method_to_call, target, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in make_lambda
filter.public_send method_to_call, target, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
result_lambda = -> { user_callback.call target, value }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block (2 levels) in halting
result_lambda = -> { user_callback.call target, value }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
result_lambda.call if result_lambda.is_a?(Proc)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block (2 levels) in default_terminator
result_lambda.call if result_lambda.is_a?(Proc)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in catch
catch(:abort) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in default_terminator
catch(:abort) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
env.halted = halted_lambda.call(target, result_lambda)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in halting
env.halted = halted_lambda.call(target, result_lambda)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
#before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in block in call
#before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in each
#before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in call
#before.each { |b| b.call(arg) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in __run_callbacks__
runner.call(e).value
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in _run_validate_callbacks
__run_callbacks__(_#{name}_callbacks, &block)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in run_validations!
_run_validate_callbacks
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations/callbacks.rb in block in run_validations!
_run_validation_callbacks { super }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in __run_callbacks__
yield if block_given?
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activesupport-5.0.0.1/lib/active_support/callbacks.rb in _run_validation_callbacks
__run_callbacks__(_#{name}_callbacks, &block)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations/callbacks.rb in run_validations!
_run_validation_callbacks { super }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in valid?
run_validations!
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/validatable.rb in valid?
super context ? context : (new_record? ? :create : :update)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/activemodel-5.0.0.1/lib/active_model/validations.rb in invalid?
!valid?(context)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in prepare_insert
invalid?(options[:context] || :create)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in insert
prepare_insert(options) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in block in create!
doc.fail_due_to_validation! unless doc.insert.errors.empty?
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/threaded/lifecycle.rb in _creating
yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/mongoid-6.0.2/lib/mongoid/persistable/creatable.rb in create!
_creating do
C:/Users/ALilland/Documents/macros/experiments/mongoid/mongoid_heroku/db_core_app/models/user.rb in block (2 levels) in <class:Routes>
User.create!(
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
proc { |a,p| unbound_method.bind(a).call }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in compile!
proc { |a,p| unbound_method.bind(a).call }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in []
route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block (3 levels) in route!
route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in route_eval
throw :halt, yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block (2 levels) in route!
route_eval { block[*args] }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in process_route
block ? block[self, values] : yield(self, values)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
catch(:pass) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in process_route
catch(:pass) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in route!
returned_pass_block = process_route(pattern, keys, conditions) do |*args|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in each
routes.each do |pattern, keys, conditions, block|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in route!
routes.each do |pattern, keys, conditions, block|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in dispatch!
route!
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in invoke
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in invoke
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in dispatch!
invoke do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in call!
invoke { dispatch! }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in invoke
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in catch
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in invoke
res = catch(:halt) { yield }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call!
invoke { dispatch! }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
dup.call!(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb in call
app.call env
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb in call
status, headers, body = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
result or app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb in context
status, headers, body = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/session/abstract/id.rb in call
context(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/logger.rb in call
#app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
env['sinatra.commonlogger'] ? #app.call(env) : super
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/head.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/show_exceptions.rb in call
#app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
result, callback = app.call(env), env['async.callback']
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
#stack.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in block in call
synchronize { prototype.call(env) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in synchronize
yield
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
synchronize { prototype.call(env) }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in block in call
result = app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in each
#apps.each do |app|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/cascade.rb in call
#apps.each do |app|
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/tempfile_reaper.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/lint.rb in _call
status, headers, #body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/lint.rb in call
dup._call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/showexceptions.rb in call
#app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/commonlogger.rb in call
status, header, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sinatra-1.4.7/lib/sinatra/base.rb in call
call_without_check(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/chunked.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/content_length.rb in call
status, headers, body = #app.call(env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in block in pre_process
response = #app.call(#request.env)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in catch
catch(:async) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in pre_process
catch(:async) do
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in process
post_process(pre_process)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/connection.rb in receive_data
process if #request.parse(data)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.1-x86-mingw32/lib/eventmachine.rb in run_machine
run_machine
C:/Ruby22/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.1-x86-mingw32/lib/eventmachine.rb in run
run_machine
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/backends/base.rb in start
EventMachine.run(&starter)
C:/Ruby22/lib/ruby/gems/2.2.0/gems/thin-1.7.0/lib/thin/server.rb in start
#backend.start { setup_signals if #setup_signals }
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/handler/thin.rb in run
server.start
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/server.rb in start
server.run wrapped_app, options, &blk
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/lib/rack/server.rb in start
new(options).start
C:/Ruby22/lib/ruby/gems/2.2.0/gems/rack-1.6.5/bin/rackup in <top (required)>
Rack::Server.start
C:/Ruby22/bin/rackup in load
load Gem.bin_path('rack', 'rackup', version)
C:/Ruby22/bin/rackup in <main>
load Gem.bin_path('rack', 'rackup', version)
I had this problem myself. The below worked for me.
You can see from the trace that the problem is the line:
when String then self.new(password)
Change that line to the following:
when String then self.create(password)
Is it possible to call methodTwo() as in
def map = [methodOne: { return "${methodTwo()}" }, methodTwo: { return "Hey" }] as MyInterface
methodTwo cannot be found at runtime by groovy (it seems that it is searching its definition inside the class where the map was defined)
You can call the method declaring the map variable before, and then referencing it:
interface MyInterface {
def methodOne()
def methodTwo()
}
def map
map = [
methodOne: { return "${map.methodTwo()}" },
methodTwo: { return "Hey" }
] as MyInterface
assert map.methodOne() == "Hey"
I want to wrap OptionParser in another function that defines some defaults, but allows
me to overwrite the banner, add separators, and add new options. I am having a hard time passing the relevant information to the on method.
Any advice on how to fix the line options.each { |o, p| opts.on(o, &p) }?
def my_opts (banner: "Usage: ruby #{File::basename($0)} [options]", separators: [], options: {})
option_parser = OptionParser.new do |opts|
opts.banner = banner
separators.each {|s| opts.separator s }
opts.separator ''
opts.separator 'Options:'
opts.on('-u', '--user USER', 'Username for authentication.') { |user| #user = user }
options.each { |o, p| opts.on(o, &p) }
opts.on_tail('--help', 'Print this help message.') { puts opts; exit }
end
return option_parser
end
opts = {['-f', '--file FILE', 'File to read']=>Proc.new { |f| #f=file } }
stdopts = my_opts( options: opts)
HA! figured it out! the line in question needs to be: options.each { |o,p| opts.on(*o, &p) }
May I know how sytanx of proc affets on its working.
in context of
-Memory consumption
-Argument passing
-scope of proc (local/global)
proc dosomething {} {
#code here
}
proc dosomething { } {
#code here
}
proc dosomething {
#code here
}
proc dosomething args {
#code here
}
proc ::dosomething {} {
#code here
}
And so on.....
They are mostly the same:
Defines a command with no arguments
proc dosomething {} {
#code here
}
Same as above, defines a command with no arguments
proc dosomething { } {
#code here
}
Not valid... should throw an error
proc dosomething {
#code here
}
Defines a command with a variable number of arguments (ie, varargs)
proc dosomething args {
#code here
}
Defines a command, in the top level namespace, with no arguments (same as the first two in most cases)
proc ::dosomething {} {
#code here
}
There's no such thing as a local proc, btw. They can be inside a namespace, but all procs are global.