I'm making a Ruby gem, and I want to put comments in the file. Would this be allowed, or would it mess up the gem? My code:
# test
Gem::Specification.new do |s|
s.name = 'My Gem' # Add a better name
s.version = '0.0.0'
s.summary = "Summary of my gem"
s.description = "More detailed description" # Maybe a tiny bit more detailed?
s.authors = ["Me"]
s.email = 'foo.bar#example.net' # Please don't email me, as I rarely look at my email
s.files = ["lib/myGem.ruby"] # Change to .rb
s.homepage =
'https://rubygems.org/gems/foobar'
end
# Add s.license
=begin
foo
bar
=end
Thanks in advance.
I'm making a Ruby gem, and I want to put comments in the file. Would this be allowed, or would it mess up the gem?
Like most programming languages, Ruby has comments. In fact, Ruby has two kinds of comments:
Single-line comments start with the token # and end with the end of the line:
#!/usr/bin/env ruby
# Shebang lines are just interpreted as comments, which is clever.
some_code # This is a comment.
# So is this.
foo.bar.
# Comments are allowed in lots of places.
baz(
# And here.
23, # And here.
42,
# And here.
:foo
)
# Even here.
.quux
Multi-line comments start with the token =begin at the beginning of a line and end with the token =end at the beginning of a line:
some_code
=begin This is a comment.
This is still the same comment.
So is this.
This is not the end of the comment: =end
But this is:
=end
If you want to know all the gory details, I recommend reading:
ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification, section 8.5 Comments
language/comment_spec.rb of The Ruby Spec Suite aka ruby/spec
Section 2.1 Lexical structure of The Ruby Programming Language by David Flanagan and Yukihiro 'matz' Matsumoto
The Code Comments sub-section in the Ruby Syntax section of the Ruby documentation
The introductory parts of Programming Ruby by Dave Thomas, Andy Hunt, and Chad Fowler
The .gemspec and Gemfile are actually just plain old Ruby files and the same syntax rules apply as in any other Ruby code. Unlike other more verbose languages (cough cough Java) Ruby is actually very well suited to writing configuration and you'll more often then not find it used instead of XML, JSON or YAML files.
They just don't have an .rb extension - as to why then thats probally a question that only the original authors can answer to. Another example of this same phenomenon is Rack's config.ru.
Related
I am looking for a list of all the magic instructions in Ruby.
For example:
#!/usr/bin/ruby -w
# encoding: windows-1252
# warn_indent: false
# frozen_string_literal: true
I just got one link mentioning some of them.
The link you mention there has a link to the Ruby source where these are defined:
static const struct magic_comment magic_comments[] = {
{"coding", magic_comment_encoding, parser_encode_length},
{"encoding", magic_comment_encoding, parser_encode_length},
{"frozen_string_literal", parser_set_compile_option_flag},
{"warn_indent", parser_set_token_info},
# if WARN_PAST_SCOPE
{"warn_past_scope", parser_set_past_scope},
# endif
};
One of these is gated based on a #define, so it may be a feature that's incomplete or yet to ship, perhaps held back for Ruby 2.7 or 3.0.
When we install Rails, we get this rails "executable":
#!/usr/bin/env ruby
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end
gem 'railties', version
load Gem.bin_path('railties', 'rails', version)
I'm wondering what the point of doing force_encoding("BINARY") is on that String. What possible values could it be that force_encoding is necessary? I would think that people would only specify versions using numbers and letters here.
This isn't a rails specific thing - it's a wrapper rubygems will generate for any ruby executable in a gem. The call to force_encoding was added in 6bf71914
The reason for the change is that the first argument might not be a version at all - we want to test if it is a version, but it could be anything and we don't want the regex check to blow up. For example some executables accept a list of file names as arguments, and those file names could be invalid in the default external encoding used by ruby.
There is a bit more discussion on the issue which prompted this change.
I want to be able to have one ruby file that can require all the common dependencies, so that other files can just have one require on this shared file.for example; I have foo.rb and bar.rb and allrequires.rb. I want to have the line require "allrequires.rb" in both foo.rb and bar.rb, but bar.rb doesn't need all the requires.
Does it matter if I use require in .rb file that do not really require that file? Could it have an impact on performance maybe?
I am currently on ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]
Update
It looks like it is not the best idea to 'share'/use all requires in both .rb files. What would be solution to that?
Right now I can think of using file name in a condition.
There's two main performance penalties:
The time taken to do the require itself. In Ruby 1.9.1 and Ruby 1.9.2, the time taken to do all the requires had worse than linear scalability - if you doubled the number of requires, it took you more than twice as long - I think it took you four times as long.
The time taken to execute the code in the file being required. If you have code like the following, then executing the code will take a non-trivial amount of time.
class MyClass
MY_CONSTANT = File.read("data.txt")
end
Another approach of conditional requiring, the following script gives no error on the JSON parser because it is named require1.rb, in scripts that have no name like require1.rb of script2.rb the gem isn't required
require 'json' if "require1.rb, script2.rb"[File.basename(__FILE__)]
p File.basename(__FILE__)
text = '[{ "name" : "car", "status": "good"}, { "name" : "bus", "status": "bad"},{ "name" : "taxi", "status": "soso"},
{"noname":"", "status" : "worse"}
]'
data = JSON.parse(text)
p data.collect { |item| item['name'] }
EDIT: here a version that uses an array
["require1.rb","script1.rb"].find{|script|require 'json' if script===File.basename(__FILE__)}
Yes, there will be a speedpanalty, you can benchmark how mutch to consider if it realy matters.
With multiple require's i put hem in my code like this so that it doens't take much screenspace.
['green_shoes','Hpricot'].each(&method(:require))
You could also do a conditional require, but that would be ugly having all around your code
begin
data = JSON.parse(text)
rescue
require 'json_pure'
data = JSON.parse(text)
end
So in short, give each rb its own require's
My final solution is (in case someone finds it useful):
requires.rb is called from web.rb or testweb.rb, rufus.rb or testrufus.rb
called_from=caller[0].split(":")[0]
puts "loading web 'requires' for file: #{called_from} ..." if (["web"].any?{|s| called_from[s]})
puts "loading web 'requires' for file: #{called_from} ..." if (["rufus"].any?{|s| called_from[s]})
puts "loading web 'requires' for file: #{called_from} ..." if (["settings"].any?{|s| called_from[s]})
require 'rubygems'
require 'socket' if (["web","settings"].any?{|s| called_from[s]})
require 'ruby-growl' if (["web","settings","rufus"].any?{|s| called_from[s]})
require 'sinatra' if (["web"].any?{|s| called_from[s]})
Thank you #Andrew for the explanation and #peter for the hint how to solve this.
I've installed the latest version of the stanfordparser and the ruby wrapper library for it. When trying to test it with a simple example from the website:
vi test.rb:
require "stanfordparser"
preproc =
StanfordParser::DocumentPreprocessor.new
puts
preproc.getSentencesFromString("This
is a sentence. So is this.")
ruby -rubygems test.rb
This
is
a
sentence
.
So
is
this
.
This is a sanity check really - am I doing something wrong, or is this a bug in the parser or wrapper?
You might be confused about how puts is formatting the output. Try this:
x = preproc.getSentencesFromString("This is a sentence. So is this.")
puts x.inspect
to make sure that you're getting what you're supposed to be getting.
This question already has answers here:
Printing the source code of a Ruby block
(6 answers)
Closed 8 years ago.
Take this example:
write_as_string { puts 'x' }
I then want to be able to do
def write_as_string(&block)
puts block.to_s
end
When I execute this, I want the output to be:
"puts 'x'"
I want to be able to receive the block and get the actual code for the block instead of executing it.
Motivation: Creating a DSL, I want to the mock to be converted into a number of other method calls, hidden from the calling code - using existing objects and methods without monkey patching them.
Any ideas on this would be great!
Thanks
Ben
If you're on Ruby 1.9, you can use the sourcify gem. It provides Proc#to_source, which is like ParseTree's Proc#to_ruby.
When using sourcify, if you have nested procs in your source code, you might have to help it along with the :attached_to option:
## (Works in Ruby 1.8) Using ParseTree (with parse_tree_extensions)
block.to_ruby
## (Works in Ruby 1.9) Using sourcify
block.to_source
## Try this if you get Sourcify::NoMatchingProcError or Sourcify::MultipleMatchingProcsPerLineError
block.to_source :attached_to => :name_of_block_in_source_code
I posted about ParseTree and Ruby 1.9 in my company's blog.
Duplicate: Printing the source code of a Ruby block
sudo gem install ParseTree
sudo gem install ruby2ruby
then
require 'rubygems'
require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'
def block_as_string &block
block.to_ruby
end
results in
irb(main):008:0> block_as_string {puts 'x'}
=> "proc { puts(\"x\") }"
You want the ruby2ruby gem, which does this nicely. Unfortunately, to analyze a block this gem depends on ParseTree, which is unsupported in Ruby 1.9.