Multiline comment in Elixir - comments

Most languages allow block comments, and multiline commands.
For example, a multiline comment in HTML looks like the following:
<!--
Warning, brave programmer:
Here be dragons.
-->
In Elixir, the closest thing I have found comes from EEx (docs).
EEx smartengine <% #comments %> seem to be discarded from source, even if they are multiline. However, this is just a workaround.
Does Elixir have a multiline comment feature, or a way to instruct the compiler to discard text from the compiled .beam file?

Elixir does not have multiline comments.
However, one very common use case for multiline comments is documenting modules and functions, for which you can use the module attributes #doc and #moduledoc together with heredocs.
defmodule MyModule do
#moduledoc """
This module is great at X
"""
#doc """
Frobnicates the given string.
"""
def frobnicate(s) do
end
end

I try to just use """ to quickly comment code a la Python, without turning it into a documentation
"""
def some_function() do
some_code
end
"""

Macros could help here to some degree:
defmodule Comment do
defmacro comment(_text) do
end
end
defmodule TestComment do
import Comment
comment """
Module
Comment
"""
def func do
comment """
Function
Comment
"""
end
end

You can simply use module attributes for multiline comments, no macro required. I typically use the following for documenting/commenting private functions:
#docp """
This is my
multi line
comment
"""

Related

Is it possible to explicitly include sub-modules or classes in Ruby?

I want to be able to statically analyze my code. That is, to know from the plain text of the file where every function and variable comes from. IDEs and text editor plugins work better when they can trace the origin of every symbol as well.
So for example, if I have application code like this:
#...
Y.some_method()
#...
Then I want to see Y in an include/import/require/extend/def statement somewhere on the page.
In other languages I use, one can explicitly choose which sub-parts of a namespace to bring in to the current context.
Python:
from X import Y
Haskell:
import X (Y)
Elixir:
alias X.Y, as: Y
And while it's possible to import all contained names in Python, the "wildcard import" is frowned upon:
from X import *
". . . they make it unclear which names are present in the namespace, confusing both readers and many automated tools."
In Ruby, it seems that this fully implicit "wildcard" way is the only way to bring in a contained name:
include X
This makes Y available, but is there some way to make this explicit? The docs for Ruby include don't show any options.
What I'd really like to do in Ruby is something like one of these:
from X include Y
include X::Y as Y
The best I've come up with so far is:
require 'x/y' ; Y = X::Y
Here's a crazy hack in the answer to another question which would enable this.
Try this. But I agree with #tadman that you should consider doing it in the Ruby way.
Object.define_singleton_method(:include) do |*mths, from: nil|
mod = from || mths.first
mod = mod.dup
if from
all_mths = mod.instance_methods
(all_mths - mths).each { |mth| mod.send :undef_method, mth }
end
super(mod)
end
module Foobar
def foo
puts :foo
end
def bar
puts :bar
end
end
class Abc
include Foobar
end
Abc.new.foo # => 'foo'
Abc.new.bar # => 'foo'
class AbcWithoutBar
include :foo, from: Foobar
end
AbcWithoutBar.new.foo # => 'foo'
AbcWithoutBar.new.bar # => NoMethodError
Ruby always executes the code that you require
And since there is no partial execution of a file there cannot be partial require.
When you require a feature Ruby locates the corresponding file using the load paths in $: and then double checks against the list of loaded files in $" and if the file has not yet been loaded executes the file.
Ruby is a dynamic language, the best way to reason about its source code is halting a running program rather than statically. In fact even class and def are not declarations but just method calls that are executed at runtime. Consider for example this contrived example
class Surprise < [Array, Hash, Fixnum, Object].sample
end
If you want to know where a method or class has been defined best use pry. You can require pry and then use binding.pry to stop anywhere in your source code and spelunk around to inspect objects and source code. Two of the most useful commands are ls and $
ls prints all methods of an object or class
$ prints the file location and source code of a method

How to define a simple global variable in an rspec test that can be accesed by helper functions

I cant figure out how to use a simple global variable in an rspec test. It seems like such a trivial feature but after much goggleing I havent been able to find a solution.
I want a variable that can be accessed/changed throughout the main spec file and from functions in helper spec files.
Here is what I have so far:
require_relative 'spec_helper.rb'
require_relative 'helpers.rb'
let(:concept0) { '' }
describe 'ICE Testing' do
describe 'step1' do
it "Populates suggestions correctly" do
concept0 = "tg"
selectConcept() #in helper file. Sets concept0 to "First Concept"
puts concept0 #echos tg?? Should echo "First Concept"
end
end
.
#helpers.rb
def selectConcept
concept0 = "First Concept"
end
Can someone point out what I am missing or if using "let" is totally the wrong method?
Consider using a global before hook with an instance variable: http://www.rubydoc.info/github/rspec/rspec-core/RSpec/Core/Configuration
In your spec_helper.rb file:
RSpec.configure do |config|
config.before(:example) { #concept0 = 'value' }
end
Then #concept0 will be set in your examples (my_example_spec.rb):
RSpec.describe MyExample do
it { expect(#concept0).to eql('value') } # This code will pass
end
It turns out the easiest way is to use a $ sign to indicate a global variable.
See Preserve variable in cucumber?
This is an old thread, but i had this question today. I just needed to define a long string to stub out a command that is in multiple files as:
# in each spec file that needed it
let(:date_check) do
<<~PWSH.strip
# lots of powershell code
PWSH
end
# in any context in that file (or a shared context)
before(:each) do
stub_command(date_check).and_return(false)
end
Searched, Stack Overflow, etc, landed on this: Note the usage of the variable doesn't change at all! (Assumes all specs require 'spec_helper')
# in spec_helper.rb
def date_check
<<~PWSH.strip
# lots of powershell code
PWSH
end
# in any context in any spec file
before(:each) do
stub_command(date_check).and_return(false)
end
I suggest you define the variable in the helper file, where it can be used by other helper code, and can be accessed from your tests.
For my project, I wanted to keep all the setup stuff in spec_helper.rb, and use those settings, plus any custom variables and methods in the tests. The following, modified from the RSpec-core 3.10 docs, is not Rails-specific.
Create a new setting for RSpec.configure called my_variable, and give it a value, like this:
# spec/spec_helper.rb
RSpec.configure do |config|
config.add_setting :my_variable
config.my_variable = "Value of my_variable"
end
Access settings as a new read-only property in RSpec.configuration from your test:
# spec/my_spec.rb
RSpec.describe(MyModule) do
it "creates an instance of something" do
my_instance = MyModule::MyClass.new(RSpec.configuration.my_variable)
end
end

yard, How to include image to documentation?

I want to include image in yard-genereted documentation, but can't find anywhere how to do this... Does anyone know how to do this?
You can just add <img /> tag to your documentation:
# Blah-blah
#
# <img src=img/1.png />
# #param [String] blah
# #return [String] blah
def foo(bar)
end
Use rdoc-image: links:
# Gets foo.
#
# rdoc-image:img/1.png
def foo(bar)
"foo"
end
is rendered by YARD into
<p>Gets foo.</p>
<p><img src="img/1.png"></p>
The rdoc-images: also works in standalone *.rdoc files.
Depending on your markup format you may have to use another mechanism. For instance, if you use Markdown, the syntax is ![Alt text](/path/to/img.jpg). In RDoc, an img tag should work, but you can check if they have added a special markup syntax for this. Note that RDoc probably (not sure) doesn't like XHTML, you should use with no ending /.

In Ruby, is there a library to make command line scripts more user friendly, prompting me what to run?

So what I do now is my Ruby scripts have a bunch of methods, and I have to comment out which method calls I don't want to call, and un-comment the one I want to fire in my command line script.
Is there a Ruby library that makes it easy to prompt the user to which function to fire?
If you want code that will selectively execute a particular method in a source file, you'll need to write a dispatch table to take the input and call whichever routine is desired.
It's all pretty standard stuff for a programmer and easily done with OptionParser and some creative use of case/when statements.
You can use ARGV to iterate over your program's arguments. There is also Getopt::Declare, which is a library for dealing with command line arguments in a similar fashion to traditional Unix utilities.
If you need something that would really prompt user during the execution of the script, you can wrap the methods you need to prompt about:
module Confirmable
def confirm_first *methods
methods.each do |meth|
alias_method "orig_#{meth}", meth
define_method meth do |*args, &block|
print "Execute #{meth}?[Yn] "
s = gets.chomp
return if s.downcase == 'n'
send "orig_#{meth}", *args, &block
end
end
end
end
class MyClass
extend Confirmable
def foo arg
puts "starting foo"
puts arg
end
confirm_first :foo
end
c = MyClass.new
c.foo "bar"
This way, each method that you mark with confirm_first will first ask you for confirmation before actually executing.

Discover the file ruby require method would load?

The require method in ruby will search the lib_path and load the first matching files found if needed. Is there anyway to print the path to the file which would be loaded. I'm looking for, ideally built-in, functionality similar to the which command in bash and hoping it can be that simple too. Thanks.
I don't know of a built-in functionality, but defining your own isn't hard. Here's a solution adapted from this question:
def which(string)
$:.each do |p|
if File.exist? File.join(p, string)
puts File.join(p, string)
break
end
end
end
which 'nokogiri'
#=> /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri
Explanation: $: is a pre-defined variable. It's an array of places to search for files you can load or require. The which method iterates through each path looking for the file you called it on. If it finds a match, it returns the file path.
I'm assuming you just want the output to be a single line showing the full filepath of the required file, like which. If you want to also see the files your required file will load itself, something like the solution in the linked question might be more appropriate:
module Kernel
def require_and_print(string)
$:.each do |p|
if File.exist? File.join(p, string)
puts File.join(p, string)
break
end
end
require_original(string)
end
alias_method :require_original, :require
alias_method :require, :require_and_print
end
require 'nokogiri'
#=> /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/rubygems-update-1.3.5/lib/rbconfig
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xml
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xml/pp
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xml/sax
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xml/node
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xml/xpath
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/xslt
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/html
# /opt/local/lib/ruby1.9/gems/1.9.1/gems/nokogiri-1.4.1/lib/nokogiri/css
# /opt/local/lib/ruby1.9/1.9.1/racc/parser.rb
$ gem which filename # (no .rb suffix) is what I use...

Resources