I'm new to vim and vimscript and getting my head with all this.
I'm trying to write a plugin that replicates the behaviour of VVDocumenter for ruby code, so, if the cursor is over a method for example and activates the plugin, it should build a skeleton to document it.
For example this code:
def method1(obj1, obj2)
// Code
end
should generate this comments:
#
#
# #param [] obj1
# #param [] obj2
# #return []
def method1(obj1, obj2)
// Code
end
I'am having trouble inserting the completion in the correct column, at the same level where def is defined.
Any help will be great!
Thanks
You can work around range and ex insert in normal mode, something like below:
1 def foo(params)
2 // code
3 end
When in normal mode:
:0,4:normal O# #param [] obj1
Vim do:
1 # #param [] obj1
2 # #param [] obj1
3 # #param [] obj1
4 # #param [] obj1
5 # #param [] obj1
6 def foo(params)
7 // code
8 end
Explain :0,4:normal O# #param [] obj1 - from 0 to 4 line, insert in normal mode O(puts before 0 line) this text # #param [] obj1.
Put this in function(not sure, can't test now):
function! PutComments()
for lineno in range(a:firstline, a:lastline)
exec ":normal O# #param [] obj1"
endfor
endfunction
Related
Let's say I have the following function:
#param foo [Array<String>]
def recursive_split(foo)
bar = []
foo.each do |elem|
bar.append(elem.split(''))
end
bar
end
How do I document with the yard #return tag that my return value is an array of arrays of strings ? Is #return [Array<Array<String>>] the right way to do it ?
The docs aren't that specific but types specifiers are recursive so the X in Array<X> can be any list of valid types so these:
Array<String>
Array<String, Symbol>
Array<Array<String, Symbol, #m>>
Array<String, Array<#m>>
...
are all valid.
The online type parser is probably the easiest way to check. That says that Array<Array<String>> is:
an Array of (an Array of (Strings))
I have an impure function like so:
# Impure function: Sets the status for a report_schedule, uses last_sent to
# calculate status
# #param report_schedule [Hash]
# #return [String] Non-useful: value of last_sent that was set
def self.set_report_schedule_status(report_schedule)
# Some logic that calculates status of report_schedule
report_schedule['status'] = status
report_schedule['last_sent'] = Time.now.to_s
end
What I want this function to do is set status and last_sent, but the side effect here is that it returns Time.now.to_s. Is there a proper way to document this?
Alternatively is my function definition wrong or should I just end with a return nil.
Should be just adding return nil
Ruby automatically appends return to the last thing executed in a method
I'm trying to document my code using YARD, however I'm having hard time figuring out how to get rid of following warning:
$ ~/.gem/ruby/2.3.0/bin/yard
[warn]: #param tag has unknown parameter name: val
in file `lib/wolfsden_myanimelist/values.rb' near line 22
Files: 4
Modules: 2 ( 2 undocumented)
Classes: 4 ( 2 undocumented)
Constants: 6 ( 6 undocumented)
Attributes: 14 ( 0 undocumented)
Methods: 4 ( 0 undocumented)
66.67% documented
In the following code:
# #overload episode
# Gets last seen episode.
# #return [Integer] last seen episode
# #overload episode=(val)
# Sets last seen episode.
# #param val last seen episode
attr_reader :episode
def episode=(val)
#status = Integer(val)
end
However I believe this is exactly how documentation ( http://www.rubydoc.info/gems/yard/file/docs/GettingStarted.md#Documentation_for_a_Separate_Attribute_Writer ) recommends to do it. So, how can I get rid of the warning?
I believe what you need to do is supply a data type for the parameter. It would look like this:
# #overload episode
# Gets last seen episode.
# #overload episode=(val)
# Sets last seen episode.
# #param [String, Integer] val Last seen episode
# #return [Integer] Last seen episode
attr_reader :episode
def episode=(val)
#status = Integer(val)
end
You can have more than one data type in a parameter -- I put String and Integer in, because a user could put in either.
Hey I have a problem with my simulation.
I am a Ruby-Starter and don't know what's wrong in my code. That is only the part with the simulation:
def mean
mean = self.reduce(:+)/self.length.to_f
return mean
end
def randn
begin
rg1 = (rand*2)-1
rg2 = (rand*2)-1
q = rg1**2 + rg2**2
end while (q == 0 || q > 1)
p = Math.sqrt((-2*Math.log(q))/q)
rn1 = rg1 * p
rn2 = rg2 * p
return rn1, rn2
end
monte_carlo = 10
ren1_sim = Array.new
ren2_sim = Array.new
monte_carlo.times {
(1..20).each{ |i|
(1..250).each { |j|
r = randn()
ren1= * Math.exp(mu_ren1 + sigma_ren1 * r[0])
# ren1 is an array with prices, mu_ren1 and sigma_ren1 are individual values
ren2= * Math.exp(mu_ren2 + chol_21 * r[0] + chol_22 * r[1])
# chol_21 and chol_22 are also individual values
ren1_sim.push(ren1)
ren2_sim.push(ren2)
}
}
}
puts ren1_sim.mean
puts ren2_sim.mean
I don't get an error without the last two puts, but when I want to calculate the average of the arrays ren1_sim and rent_sim I get the error:
undefined method 'mean' for #<Array:0x2acf318> (NoMethodError)
Do you know how to fix that?
You're trying to invoke mean on an Array, which is not a method of Array. Perhaps you meant to use Statsample::Vector, which is Statsample's extension of Array, and does have mean?
ren1_sim = Statsample::Vector.new
ren2_sim = Statsample::Vector.new
You can also call to_vector on an Array instance to get a Statsample::Vector.
You've defined a mean method at the top of your file, but that just creates a method on the top level object, and you're trying to call it on an individual array. You could either change that code to
def mean(array)
array.reduce(:+)/array.length.to_f
end
and then change your usage of it later on to mean(ren1_sim)
or change your code so that you are adding the method to array, i.e.
class Array
def mean
self.reduce(:+)/self.length.to_f
end
end
have a look at this post to calculate the average of a array
How do I create an average from a Ruby array?
When I type this:
puts 'repeat' * 3
I get:
>> repeat repeat repeat
But it's not working if I do this:
puts 3 * 'repeat'
Why?
In Ruby, when you call a * b, you're actually calling a method called * on a. Try this, for example:
a = 5
=> 5
b = 6
=> 6
a.*(b)
=> 30
c = "hello"
=> "hello"
c.*(a)
=> "hellohellohellohellohello"
Thus <String> * <Fixnum> works fine, because the * method on String understands how to handle integers. It responds by concatenating a number of copies of itself together.
But when you do 3 * "repeat", it's invoking * on Fixnum with a String argument. That doesn't work, because Fixnum's * method expects to see another numeric type.