I'm working with clang-format for my Objective-C project, but I'm having difficulty setting it up properly.
Here's my desired result:
- (NSString *)someMethod
{
return #"My String";
}
Here's the actual result after formatting:
- (NSString *)someMethod {
return #"My String";
}
Here's my .clang-format file:
BasedOnStyle: WebKit
AlignTrailingComments: true
ColumnLimit: 120
IndentWidth: 2
KeepEmptyLinesAtTheStartOfBlocks: false
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
TabWidth: 2
UseTab: Never
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
What setting do I need to change to get the formatter to put a line break before the opening brace of an Objective-C method?
For any fine-tuning of your clang-format you are much better off never to use BasedOnStyle because that for me just creates random and hard to debug results.
Easiest way to do this would be probably to set: BreakBeforeBraces: Custom and then set everything up the way you want it in as it says in the documentation:
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
Related
Output of this is:
print(arr.shape)
print(arr.flags)
Output:
(676, 3516)
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : False
WRITEABLE : False
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
But when I trim the rows using:
arr = arr[preds<0]
I get this output
(670, 3516)
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
Now, when I use catboost to predict on the trimmed version of array, it takes 2x the time to predict compared to the original array. Catboost needs F_CONTIGUOUS array only I guess, not sure what contiguous array means.
How can I make the trimmed version F_CONTIGUOUS?
Since I have to change state.active from false to true alot through #click, I was wondering if there is a shorter way in doing so than:
state.active = !state.active
I've tried #click="!state.active" which doesn't seem to work.
I'm tryna improve my RSpec skills following the bests practices.
I have a simple method is_multiple_of_3_or_5? and I'm implementing a test for it using simple testing values. My first approach was:
describe '#is_multiple_of_3_or_5?' do
context "when input is multiple of 3 or 5" do
expect(is_multiple_of_3_or_5?(3)).to be true
expect(is_multiple_of_3_or_5?(5)).to be true
expect(is_multiple_of_3_or_5?(51)).to be true
expect(is_multiple_of_3_or_5?(45)).to be true
end
end
I like it because it's very short and the test cases are simple, so no need to complicate it.. But I've read in the RSpec style guide that it should be only one expectation per example.
So I refactored in 2 other ways:
One it per example:
describe '#is_multiple_of_3_or_5?' do
context 'when input is multiple of 3 or 5' do
it "is true for 3" do
expect(is_multiple_of_3_or_5?(3)).to be true
end
it "is true for 5" do
expect(is_multiple_of_3_or_5?(5)).to be true
end
it "is true for 51" do
expect(is_multiple_of_3_or_5?(51)).to be true
end
it "is true for 45" do
expect(is_multiple_of_3_or_5?(45)).to be true
end
end
end
Drying up with a subject block
describe '#is_multiple_of_3_or_5?' do
context 'when input is multiple of 3 or 5' do
subject { is_multiple_of_3_or_5?(input) }
context 'when input is 3' do
let(:input) { 3 }
it { is_expected.to be true }
end
context 'when input is 5' do
let(:input) { 5 }
it { is_expected.to be true }
end
context 'when input is 51' do
let(:input) { 51 }
it { is_expected.to be true }
end
context 'when input is 45' do
let(:input) { 45 }
it { is_expected.to be true }
end
end
end
So I have 2 questions:
In the case of theses 2 last versions, the test became really bigger, is it really worth it? Considering that the values tested are simple integers?
Which one of these 2 versions are better formatted?
Thank you for anyone who could help me take better perspective on RSpec!
I'm have the following code, for example:
[self.service loadDataForId:#"id"
successBlock:^(NSDictionary *dictionary) {
NSLog(#"%#", dictionary);
}
errorBlock:^(NSError *error) {
NSLog(#"%#", error);
}];
When I apply clang-format on it, it turns into:
[self.service loadDataForId:#"id"
successBlock:^(NSDictionary *dictionary) {
NSLog(#"%#", dictionary);
}
errorBlock:^(NSError *error) {
NSLog(#"%#", error);
}];
As you can see, code not aligned with a colon.
If I have a code without errorBlock, clang-format works fine
[self.service loadDataForId:#"id"
successBlock:^(NSDictionary *dictionary) {
NSLog(#"%#", dictionary);
}
errorBlock:nil];
I used clang-format version 8.0.0 (tags/google/stable/2019-01-18). If I used predefined styles (LLVM, Google, Chromium, Mozilla, WebKit), then I have the same problem
How to set up clang-format correct? My following settings file:
---
Language: ObjC
AccessModifierOffset: 0
ConstructorInitializerIndentWidth: 4
ObjCBlockIndentWidth: 4
ContinuationIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
ColumnLimit: 0
IndentWidth: 4
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
TabWidth: 4
UseTab: Never
IndentFunctionDeclarationAfterType: true
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpaceBeforeAssignmentOperators: true
CommentPragmas: '^ IWYU pragma:'
SpaceBeforeParens: ControlStatements
AlignOperands: true
BinPackArguments: false
BinPackParameters: false
AlignAfterOpenBracket: Align
ObjCBinPackProtocolList: Never
AllowShortBlocksOnASingleLine: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
AfterClass: false
AfterControlStatement: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
BeforeCatch: false
AfterExternBlock: false
AfterUnion: false
AfterStruct: false
BeforeElse: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
IncludeBlocks: Merge
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: -1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
Sorbet infers the type of true to be TrueClass, and the type of false to be FalseClass. Often it would be nice if it would instead infer T::Boolean. Why not special case true and false to have the type T::Boolean instead?
It's possible to work around this problem with a type annotation, initializing variables with T.let(true, T::Boolean) for example, but it would be nice to not have to provide this extra information.
# typed: true
T.reveal_type(true) # Revealed type: `TrueClass`
T.reveal_type(false) # Revealed type: `FalseClass`
extend T::Sig
sig {params(x: T::Boolean).void}
def test(x)
var = true
10.times do
var = false # Changing the type of a variable in a loop is not permitted
end
end
The assignment of false to var in the loop causes an error to be raised, as the type of var is being changed from TrueClass to FalseClass.
Sorbet's flow-sensitive typing is made more precise by true and false having different types. In the following example, a variable with the value true is used as the condition of an if-statement:
# typed: true
val = true
if val
puts "true!"
else
puts "false?"
end
The resulting error from sorbet is:
editor.rb:7: This code is unreachable https://srb.help/7006
7 | puts "false?"
^^^^^^^^
Errors: 1
Behind the scenes, sorbet knows that the value being examined has the type TrueClass, and that the value true is the only value of that type. As a result, it knows that val cannot be false, and that the else branch will never be executed.
Now consider the case where we instead infer the type T::Boolean for true and false. T::Boolean is a synonym for T.any(TrueClass, FalseClass), so in the example it now means that val could be either true or false. As a result, it becomes impossible to tell from the type alone that the else branch will not be executed.
The flow-sensitive typing documentation on sorbet.org has more information on this topic.
Asked the same question today as well.
Ended up fixing it as you suggested with type annotations and initializing with T.let(true, T::Boolean)
# typed: true
extend T::Sig
sig {params(x: T::Boolean).void}
def test(x)
var = T.let(true, T::Boolean)
10.times do
var = T.let(false, T::Boolean)
end
end