begin
File.open("Googoo.txt")
rescue e
puts "\n*** \"#{e}\" ***\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"
end
Is it possible to " #define" a string like
"\n*** \"#{e}\" ***\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"
to avoid copy/pasting it?
I tried:
macro msg
"#{ {{"\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"}}}"
end
begin
File.open("Googoo.txt")
rescue err
puts err.to_s
puts msg
end
``
But I must have done something wrong...
If I use a macro, LINE and FILE are those where the Macro is defined, not those where the macro is inserted (unlike C’s “#define”):
macro msg
{{"\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"}}
end
begin
File.open("Googoo.txt")
rescue err
puts err.to_s
puts msg
end
That’s because you expand these magic constants in the macro context.
For what you want to do, you don’t need to do anything in the macro body. It’s just the original string literal:
macro msg
"\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"
end
1 Like
Thank you. I’m new to macros (I’ve been using mostly Golang for a long time).
Do you know about a tutorial about this topic?
Here is a convenient formulation :
# testing.cr
require "./error_message"
begin
File.open("Googoo.txt")
rescue err
puts errorMessage(err)
end
# error_message.cr
macro errorMessage(err)
"\n*** \"#{err}\" ***\n-> in file: #{__FILE__} \n-> on line: #{__LINE__}\n\n"
end
Result:
>>crystal testing.cr
*** "Error opening file with mode 'r': 'Googoo.txt': No such file or directory" ***
-> in file: /Users/sergehulne/Documents/code/Crystal/fibers/logic.cr
-> on line: 15
Note that for this example using a plain def with default values is enough
begin
File.open("Googoo.txt")
rescue err
puts errorMessage(err)
end
def errorMessage(err, *, file = __FILE__, line = __LINE__)
"\n*** \"#{err}\" ***\n-> in file: #{file} \n-> on line: #{line}\n\n"
end
2 Likes
No, it’s not: lt would yield the wrong line (and file, if stored in another file).
Pretty sure it would be fine because __FILE__
and __LINE__
would default to the file and line of the invocation of the method, not where the method is defined.
bar.cr
def errorMessage(err, *, file = __FILE__, line = __LINE__)
"\n*** \"#{err}\" ***\n-> in file: #{file} \n-> on line: #{line}\n\n"
end
foo.cr
require "./bar"
begin
File.open("Googoo.txt")
rescue err
puts errorMessage(err)
puts errorMessage(err)
puts errorMessage(err)
end
Output:
*** "Error opening file with mode 'r': 'Googoo.txt': No such file or directory" ***
-> in file: /home/george/foo.cr
-> on line: 6
*** "Error opening file with mode 'r': 'Googoo.txt': No such file or directory" ***
-> in file: /home/george/foo.cr
-> on line: 7
*** "Error opening file with mode 'r': 'Googoo.txt': No such file or directory" ***
-> in file: /home/george/foo.cr
-> on line: 8
Works fine.
1 Like
Ok! Perhaps the pb.was that my earliest version erroneously contained double curly braces : {{“…”}}.