Create directory with ARGV (ruby) - ruby

I created this program to create a folder in the program directory if there is an ARGV.
def check_if_user_gave_input
abort("mkdir: missing input") if ARGV.empty?
end
def get_folder_name
return folder_name = ARGV.first
end
def create_folder(name)
Dir.mkdir(name)
end
def perform
folder_name = get_folder_name
create_folder(folder_name)
end
perform
So, if I run this program in my terminal everything is OK. But, if I try it in my terminal and don't write anything after $ ruby app.rb I get a nice error message like this and I don't see the string "mkdir: missing input"
Traceback (most recent call last):
3: from app.rb:18:in `<main>'
2: from app.rb:15:in `perform'
1: from app.rb:10:in `create_folder'
app.rb:10:in `mkdir': no implicit conversion of nil into String (TypeError)
How to fix this? Thank you.

Just add check_if_user_gave_input method in perform
def check_if_user_gave_input
abort("mkdir: missing input") if ARGV.empty?
end
def get_folder_name
ARGV.first
end
def create_folder(name)
Dir.mkdir(name)
end
def perform
check_if_user_gave_input
folder_name = get_folder_name
create_folder(folder_name)
end
perform

Related

Ruby Error: private method `execute' called

Edit: To save confusion, I've added the actual code I'm having the issue with instead of the example. Same error as before. This is an interactive shell, and for example if I type ls -a it attempts to call the 'execute' method, but instead crashes saying that the method is private. I don't understand how it's private, nor how to work around this.
$ ruby shell.rb
ls -a
Traceback (most recent call last):
3: from shell.rb:59:in `<main>'
2: from shell.rb:6:in `main'
1: from shell.rb:6:in `loop'
shell.rb:10:in `block in main': private method `execute' called for #<Command:0x00005637cb75b1e8 #args=["ls"#0, "-a"#3]> (NoMethodError)
Ruby Code:
require 'readline'
require 'parslet'
def main
loop do
cmdline = Readline.readline("> ", true)
# p tree
tree.execute
end
end
def parse_cmdline(cmdline)
raw_tree = Parser.new.parse(cmdline)
Transform.new.apply(raw_tree)
end
class Parser < Parslet::Parser
root :cmdline
rule(:cmdline) { command }
rule(:command) { arg.as(:arg).repeat(1).as(:command) }
rule(:arg) { match[%q{^\s}].repeat(1) >> space? }
rule(:space?) {space.maybe }
rule(:space) { match[%q{\s}].repeat(1).ignore }
end
class Transform < Parslet::Transform
rule(command: sequence(:args)) { Command.new(args) } #ls
rule(arg: simple(:arg)) { arg } # -a
end
class Command
def initialize(args)
#args = args
end
end
def execute
spawn(*#args)
end
main
Why it doesn't work?
tree = (3) # tree is an integer
tree.execute # integers don't have an execute method
It's unclear what you are trying to do?
Try this instead:
I think you are trying to create a tree class? It's hard to say.
class Tree
def initialize(tree)
#tree = tree
end
def execute
puts #tree
end
end
def test
loop do
tree = Tree.new(3)
tree.execute
end
end
test
Because you are doing an infinite loop, you'll have to press: "CTRL + C" to kill the program, when you want it to stop (That'll work for Ubuntu, but not sure how it will work with other linux based distros or macs or windows).

Wrong Number of Arguments in Initialize (given 0, expected 1)

I am following along with a tutorial at:
http://neurogami.com/content/neurogami-10_minutes_to_your_first_Ruby_app/#sidebar4
I have checked and rechecked the code, and I do not understand why ruby is not reading my variable app_map as a valid argument.
I have searched online for similar questions, and they exist, yet I can not understand why this variable is not working. I also am not exactly sure what initialize means, as I am an absolute beginner with Ruby. Any insight would be greatly appreciated.
#!/usr/bin/env ruby
class Launcher
def initialize (app_map)
#app_map = app_map
end
#execute the given file using the associate app
def run file_name
application = select_app file_name
system "#{application} #{file_name}"
end
#given a file, lookup the matching application
def select_app file_name
ftype = file_type file_name
#app_map[ ftype ]
end
#return the part of the file name string after the last '.'
def file_type file_name
File.extname( file_name ).gsub( /^\./, '' ).downcase
end
end
launcher = Launcher.new
end
I am not sure what this code is supposed to run, but I have multiple error messages.
tinyapp.rb:8:in `initialize': wrong number of arguments (given 0, expected 1) (ArgumentError)
from tinyapp.rb:30:in `new'
from tinyapp.rb:30:in `<main>'
In this line, you are instantiating a Launcher:
launcher = Launcher.new
That will call the initialize method on it. That method expects an argument:
def initialize (app_map)
#app_map = app_map
end
In order to resolve the error, you will need to pass in a parameter for the app_map argument. I don't know what it's supposed to actually be here, but that'll look something like this:
launcher = Launcher.new(the_app_map)

Syntax error unexpected token '('

I kept running to this unexpected error token. I wanted the program to run without invoking ruby. For instances, instead of ruby program1.rb, i should be able to program1.rb poem.txt.
This is the error message:
program1.rb --backwards poem.txt
./program1.rb: line 1: syntax error near unexpected token `('
./program1.rb: line 1: `def backlines(line_array)'
This is my code:
def backlines(*line_array)
end
def backwards(line_array)
end
def backchars(line_array)
end
def main
file = File.new(ARGV[1], "r") do |file|
line_array = file.readlines
*line_array = line_array.reverse
if ARGV[0] == "--backlines"
*backwards_poem = backlines(line-array)
#you can manipulate "backwards_poem" however you want
elsif ARGV[0] == "--backwards"
backwards(line_array)
elsif ARGV[0] == "--backchars"
backchars(line_Array)
end
# passing a *line_array into a function
end
main
Have you executed ruby in your script at the top? eg:
#!/usr/bin/ruby
#!/usr/bin/ruby
def backlines(*line_array)
end
def backwards(line_array)
end
def backchars(line_array)
end
def main
puts ARGV
# File open not new ... this block requires the end below.
File.open(ARGV[1], "r") do |file|
line_array = file.readlines
*line_array = line_array.reverse
if ARGV[0] == "--backlines"
*backwards_poem = backlines(line_array)
#you can manipulate "backwards_poem" however you want
elsif ARGV[0] == "--backwards"
backwards(line_array)
elsif ARGV[0] == "--backchars"
backchars(line_array)
end
end
# passing a *line_array into a function
end
this should start you off if your call it like ./program1.rb --backwards file
you also had line-array , line_array and line_Array which should al be one variable i think.

ruby filename path to string error

This is my code:
file = File.open('result.txt', 'w+').read
path = Dir[ENV['HOME'] + '/Desktop/Test/*.txt']
file.puts "this is a #{path} test: "
It comes up with an error:
C:/Users/User/RubymineProjects/Comparison/test.rb:5:in `<top (required)>': private method `puts' called for "":String (NoMethodError)
from -e:1:in `load'
from -e:1:in `<main>'
my intended result is:
this is a C:/Users/User/Desktop/Test/new_1.txt test:
i've tried this:
puts "this is a #{path[0]} test: "
which achieves what i want but as soon as i do file.puts it comes up with the same error again.
When you do file.puts here, you're sending a method #puts to a string object that's now stored in the variable file. This is because File#read method returns a string. So, on the first line, file takes the contents of the result.txt and then stores it in the variable file. Then you're callingputson that string. AndString#puts` is a private method, so you can't use it the way you used it in the code above.
If your intention is to write the result this is a C:/Users/User/Desktop/Test/new_1.txt test:, then you need to use the File.open method this way:
File.open('result.txt', 'w+') do |file|
path = Dir[ENV['HOME'] + '/Desktop/Test/*.txt']
file.puts "this is a #{path} test: "
# whatever else needs to be written goes here
end
Or, if you prefer the imperative style instead of the block style:
file = File.new('result.txt', 'w+')
# If you prefer `open`, that works too!
# file = File.open('result.txt', 'w+')
path = Dir[ENV['HOME'] + '/Desktop/Test/*.txt']
file.puts "this is a #{path} test: "
# ensure this is closed, or you'll have memory issues if you do this often
file.close

My very simple custom Puppet type and provider does not work

I am reading about how to create custom types and providers in Puppet.
But I am getting the error:
Error: Could not autoload puppet/provider/createfile/ruby: undefined method `[]' for nil:NilClass
when running the below code:
mymodule/lib/puppet/type/filecreate.rb
require 'fileutils'
Puppet::Type.newtype(:filecreate) do
ensurable do
defaultvalues
defaultto :present
end
#doc = "Create a file."
newproperty(:name, :namevar => true) do
desc "The name of the file"
end
newproperty(:path) do
desc "The path of the file"
end
end
mymodule/lib/puppet/provider/filecreate/ruby.rb
require 'fileutils'
Puppet::Type.type(:filecreate).provide(:ruby) do
desc "create file.."
puts resource[:name] # this line does not seem to work, why?
puts resource[:path] # this line does not seem to work, why?
def create
puts "create file..."
puts resource[:name]
end
def destroy
puts ("destroy file...")
FileUtils.rm resource[:path]+resource[:name]
end
# Exit method never seems to be called
def exists?
puts "is method beeing called???"
File.exists?(resource[:path])
end
end
I guess the way of fetching the parameter values, puts resource[:name] not is correct. So how can I fetch the filename file.txt declared as the namevar for my custom type filecreate (see below)?
Also, method exists does not seem to be called. Why?
And my init.pp contains this simple code:
class myclass {
filecreate{'file.txt':
ensure => present,
path => '/home/myuser/',
}
}
Your puts calls do not work because you try and access an instance attribute (resource) on the class level. It makes no semantic sense to access the values in this context. Remove those calls.
Generally, it is better to use Puppet.debug instead of puts to collect this kind of information.
To find out where such errors come from, call puppet with the --trace option.

Resources