I am having some trouble with ruby syntax in chef (the configuration management tool).
The difference I am dealing with is assigning attributes such as below:
runner = ChefSpec::Runner.new(platform: "ubuntu", version: version)
runner = ChefSpec::Runner.new(:platform => "ubuntu", :version => version)
I need to be able to switch between these two syntax's as they seem to work in different versions of chef/ruby - we will be upgrading but for now need a fix.
I'm novice with regexp, but have been trying like this in python:
for line in fileinput.input(inplace=1, backup='.bak'):
line = re.sub('(\w\w...): ',':"\1" =>', line.rstrip())
print(line)
I don't know what the attribute name will be, or what precedes it, only that a single : follows a word (of 2 or more characterss). I'm happy assuming that there will always be a space after the : but I seem to be having trouble "picking up" the attribute name to replace and re-use later.
the following should work:
for line in fileinput.input(inplace=1, backup='.bak'):
line = re.sub('(\w+): ', ':\g<1> => ', line.rstrip())
print(line)
see regex demo, or repl demo
Related
I have the following JISON file (lite version of my actual file, but reproduces my problem):
%lex
%%
"do" return 'DO';
[a-zA-Z_][a-zA-Z0-9_]* return 'ID';
"::" return 'DOUBLECOLON'
<<EOF>> return 'ENDOFFILE';
/lex
%%
start
: ID DOUBLECOLON ID ENDOFFILE
{$$ = {type: "enumval", enum: $1, val: $3}}
;
It is for parsing something like "AnimalTypes::cat". It works fine for things like "AnimalTypes::cat", but the when it sees dog instead of cat, it asumes it's a DO instead of an id. I can see why it does that, but how do I get around it? I've been looking at other JISON documents, but can't seem to spot the difference that (I assume) makes those work.
This is the error I get:
JisonParserError: Parse error on line 1:
PetTypes::dog
----------^
Expecting "ID", "enumstr", "id", got unexpected "DO"
Repro steps:
Install jison-gho globally from npm (or modify code to use local version). I use Node v14.6.0.
Save the JISON above as minimal-repro.jison
Run: jison -m es -o ./minimal.mjs ./minimal-repro.jison to create parser
Create a file named test.mjs with code like:
import Parser from "./minimal.mjs";
Parser.parser.parse("PetTypes::dog")
Run node test.mjs
Edit: Updated with a reproducible example.
Edit2: Simpler JISON
Unlike (f)lex, the jison lexer accepts the first matching pattern, even if it is not the longest matching pattern. You can get the (f)lex behaviour by using
%option flex
However, that significantly slows down the scanner.
The original jison automatically added \b to the end of patterns which ended with a literal string matching an alphabetic character, to make it easier to match keywords without incurring this overhead. In jison-gho, this feature was turned off unless you specify
%option easy_keyword_rules
See https://github.com/zaach/jison/wiki/Deviations-From-Flex-Bison#user-content-literal-tokens.
So either of those options will achieve the behaviour you expect.
I'm new to ruby and Chef and am running to an issue with syntax when defining attributes in my cookbook. Below is relevant code:
default[:my_cookbook][:stuff] = {
:foo_bar => {
:grok => ['Hi'],
:2grok => ['Bye'],
...
It appears I can't use a number to begin 2grok.. Is there a way to escape this, or what would be the proper syntax to use '2grok'?
If you want to start a symbol with a digit, you need to enclose it in quotes:
:'2grok' => ['Hi']
If you use double quotes, ruby interpolates string inside:
:"#{1 + 1}grok"
Also, you can use percent-notation:
%s{2grok}
Finally, you can get the symbol by calling to_sym method on a String:
'2grok'.to_sym => ['Hi']
Mladen's answer is correct in term of Ruby. You can use a number at the beginning of symbol's name only using quotes. Keep in mind that you will have to use them to access the value from hash too. However you shouldn't use symbols for defining attributes in your cookbooks. Chef Style Guide recommends using strings instead.
Having just started with Ruby and while following a tutorial, the result was shown as:
a + b # => 3
I have never seen such a possibility; that seems so handy! Could you please tell me what it is? is it proprietary or is it for everyone?
Josh Cheek's seeing is believing. Apparently you can run it over your code, or it can be integrated in several editors.
Reconfigure Your REPL
The # symbol is a comment in Ruby. By default, most Ruby REPLs (e.g. irb or pry) will use => to prefix the return value of your last expression.
In IRB, you can modify this prefix so that each return value is prefixed by a different string. You can do this through the IRB::Context#return_format method on your conf instance. For example:
$ irb
irb(main):001:0> conf.return_format = "#=> %s\n"
#=> "#=> %s\n"
irb(main):002:0> 1 + 2
#=> 3
More permanent changes would have to be made in your IRB configuration file by customizing the prompt through the IRB.conf[:PROMPT] Hash and then setting IRB.conf[:PROMPT_MODE] to your custom prompt, but in my opinion the solution above is simpler even though you have to run it within the current REPL session rather than saving it as a default.
I know there's lots of similar questions but I haven't found a solution yet. I'm trying to use the CSV parsing library with Ruby 1.9.1 but I keep getting:
/usr/lib/ruby/1.9.1/csv.rb:1925:in `block (2 levels) in shift': Illegal quoting in line 1. (CSV::MalformedCSVError)
My CSV files were created in Windows 7 but it's Ubuntu 12.04 that I'm using to run the Ruby script, which looks like this:
require 'csv'
CSV.foreach('out.csv', :col_sep => ';') do |row|
puts row
end
Nothing complicated, just a test, so I assumed it must be the Windows control characters causing problems. Vim shows up this:
"Part 1";;;;^M
;;;;^M
;;;;^M
Failure to Lodge Income Tax Return(s);;;;^M
NAME;ADDRESS;OCCUPATION;"NO OF CHARGES";"FINE/PENALTY £"^M
some name;"some,address";Bookkeeper;3;1,250.00^M
some name;"some,address";Haulier;1;600.00^M
some name;"some,address";Scaffolding Hire;1;250.00^M
some name;"some,address";Farmer;2;500.00^M
some name;"some,address";Builder;2;3000.00
I've tried removing those control characters for carraige returns that Windows added (^M), but %s/^V^M//g and %s/^M//g result in no pattern found. If I run %s/\r//g then the ^M characters are removed, but the same error still persists when I run the Ruby script. I've also tried running set ffs=unix,dos but it has no effect. Thanks.
Update:
If I remove the double quotes around the Part 1 on the first line, then the script prints out what it should and then throws a new error: Unquoted fields do not allow \r or \n (line 10). If I then remove the \r characters, the script runs fine.
I understand that I would have to remove the \r characters, but why will it only work if I unquote the first value?
The problem causing the Illegal quoting error was due to a Byte-Order-Mark (BOM) at the very beginning of the file. It didn't show up in editors, but the Ruby CSV lib was choking on it unless :encoding => 'bom|utf-8' was set.
Once that was fixed, I still needed to remove all the '^M' characters by running %s/\r//g in vim. And everything was working fine after that.
When I was developing my project on my local file I had this line in code which worked correctly:
#json = Location.qty_of_deliv_from(params[:from_rc])
.qty_of_deliv_to(params[:to_rc])
When I deployd with passenger I get a syntax error on this line which goes avay if I have all the code in the same line:
#json = Location.qty_of_deliv_from(params[:from_rc]).qty_of_deliv_to(params[:to_rc])
Is this a known issue?
Perhaps your server's ruby version is different and parses differently?
In any case, in Ruby, when writing multiline code you typically want to make sure your lines to be wrapped are syntactically incomplete, so as not to confuse the parser, e.g. by using a hanging dot, instead.
Location.qty_of_deliv_from(params[:form_rc]).
qty_of_deliv_to(params[:to_rc])
Or you can use the backslash to escape the new line:
Location.qty_of_deliv_from(params[:form_rc]) \
.qty_of_deliv_to(params[:to_rc])