Sarah McLaughlin
---Follow me through
DevAcademy
Reflection
Time and habits
Technical (part 1)
Technical (part 2)
Emotional intelligence
Technical (part 3)
Meditation process
Technical (part 4)
Daily mindfulness
Self confidence
Technical (part 5)
Technical (part 6)
Control
Motivation
JavaScript scope
Connection
XX
XX


Change Log: 2.065.0
Download D 2.065.0
released February 24, 2014
Language Changes
- Goto jumps now cannot skip variable declarations.
- All instantiated functions now infer their attributes.
- Add a new type qualifier inout const.
- Entire slicing operation of built-in tuple is now accepted.
- Packages and module names now have no type.
- Const and immutable fields with initializers are now deprecated.
- Deprecate unordered floating point comparisons.
- Deprecate .min property for floating-point types.
- CTFE can handle overlapped union fields.
- Add a new trait getAliasThis.
- Mixing struct constructors and static opCall is no longer allowed.
Library Changes
Linker Changes
List of all bug fixes and enhancements in D 2.065.
Compiler Changes
- Extensionless D source file names can now be run when using the -run switch:
On Posix systems it is frequently useful to have a shebang line at the start of an extensionless file, which marks the tool used to compile the script. It's now possible to use this technique with D, e.g. the following is a D source file with the file name "my-script":
#!rdmd void main() { }
Note: This does not allow an arbitrary extension, as D source files need to be proper D identifiers.
Note: This feature is not available on Windows, as Windows does not have extensionless executable files.
Note: When compiling, and in order to avoid the default behavior of generating an extensionless executable which would overwrite the source file, the compiler will generate "a.out" instead.
Language Changes
- Goto jumps now cannot skip variable declarations:
For a very long period, the following code had been allowed by mistake, but it is prohibited now:
import std.stdio; void main() { goto Label; // Error: goto skips declaration of variable v int v = 42; Label: writeln(v); }
- All instantiated functions now infer their attributes:
Regardless of how directly or indirectly a function is instantiated, its attributes will still be inferred:
struct S(T) { T square(T x) { T calc() { return x * x; } return calc(); } static double pi() { return 3.141592; } } void main() pure @safe nothrow { S!int s; // S!int.square and its nested function calc are instantiated functions, so // their attributes are inferred as pure and callable from main() assert(s.square(2) == 4); // ok // static member function attributes are also inferred now auto pi = typeof(s).pi(); }
- Add a new type qualifier inout const:
Until now, the common type of immutable(T) and inout(T) had been const(T). But that loses the inout information, which might then refuse some valid code. Now the type becomes inout(const(T)), which meaningfully propagates the appropriate type qualifier.
inout(const(int))[] foo(bool condition, inout(int)[] x, immutable(int)[] y) { static assert(is(typeof(condition ? x : y) == inout(const(int))[])); return condition ? x : y; } void main() { int[] marr = [1,2,3]; const(int)[] carr = [4,5,6]; immutable(int)[] iarr = [7,8,9]; // inout(const(int))[] can go back to const(int)[] or immutable(int)[]. static assert(is(typeof(foo(true, marr, iarr)) == const(int)[])); static assert(is(typeof(foo(true, carr, iarr)) == const(int)[])); static assert(is(typeof(foo(true, iarr, iarr)) == immutable(int)[])); }
- Entire slicing operation of built-in tuple is now accepted:
Bugzilla 8244: cannot slice a type tuple with '[]' in locations where a type is valid:
import std.typetuple; alias Types = TypeTuple!(int, double, string); // Was error in 2.064, but allowed from 2.065. alias Types2 = Types[]; static assert(is(Types == Types2));
- Packages and module names now have no type:
Bugzilla 9081: Modules shouldn't have a type
import std.stdio; // Both had printed 'void' in 2.064. // From 2.065, both will cause "has no type" error. pragma(msg, typeof(std)); pragma(msg, typeof(std.stdio));
By the change, an idiom that used to work is(typeof(package_or_module_name)) is changed to not work. Instead use: __traits(compiles, package_or_module_name).
- Const and immutable fields with initializers are now deprecated:
Eventually, they will be changed to occupy space in the object. Such fields should now be changed to enum or static. See also the release note in 2.063.
Related to that, void-initialized const or immutable fields will now occupy space in the object instance ahead of schedule:
struct S { const int[1000] x = void; this(int n) { // Was disallowed in 2.064. // From 2.065 x is a field of runtime object. x[] = n; } } // S.sizeof had been 1 in 2.064. // From 2.065, field s.x occupies space in the object. static assert(S.sizeof == int.sizeof * 1000); void main() { S s = S(3); foreach (e; s.x) { assert(e == 3); // OK } }
- Deprecate unordered floating point comparisons:
Bugzilla 10369: Deprecate unordered floating point comparisons
- Deprecate .min property for floating-point types:
Bugzilla 10439: Deprecate float.min, double.min, real.min
- CTFE can handle overlapped union fields:
Example code:
union U { size_t x; int* y; } bool test() { U u; assert(u.x == 0); // In here, reading u.y will cause CTFE error. u.y = [1,2,3].ptr; // Writing value to overlapped field u.y will make corresponding field u.x invalid. assert(u.y[0..3] == [1,2,3]); // u.y holds valid field and reading it is allowed // In here, reading u.x will cause CTFE error. u.x = 10; // Set value to u.x again. assert(u.x == 10); // OK // In here, reading u.y will cause CTFE error. return true; } static assert(test()); // run CTFE
Bit image reinterpretation by using two overlapped union fields is not allowed during CTFE.
- Add a new trait getAliasThis:
The new getAliasThis trait will return a tuple of field names which are marked as the subtypes of an aggregate type. For example:
struct S { string var; alias var this; } static assert(__traits(getAliasThis, S)[0] == "var");
Note: Multiple subtyping is not yet implemented in D, therefore this trait will always return a tuple of length 1.
- Mixing struct constructors and static opCall is no longer allowed:
This was not implemented correctly and caused ambiguities.
Example:
struct S { this(int i) {} static S opCall() // disallowed due to constructor { return S.init; } }
Note: static opCall can be used to simulate struct constructors with no arguments, but this is not recommended practice. Instead, the preferred solution is to use a factory function to create struct instances.
Library Changes
- Many functions in std.algorithm can now be used as predicates to other functions:
Functions such as any, all, canFind and equal are now templates, which allows them to be used as predicates to other templates, as well as allowing the user to alias an instantiation of any such templates. For an example of how this allows terser syntax in user-code, in the following example the programmer wants to check whether all the strings in a string array have at least one ASCII digit:
import std.algorithm : all; import std.ascii : isDigit; void main() { string[] inputs = ["foo1", "bar2"]; bool allContainDigit; foreach (input; inputs) { if (!any!isDigit(input)) // none of the characters are ASCII digits { allContainDigit = false; break; } } }
But it is now simpler to use the any template itself as a predicate. We can make it a predicate to another useful template, the all template:
import std.algorithm : any, all; import std.ascii : isDigit; void main() { string[] inputs = ["foo1", "bar2"]; bool allContainDigit = all!(any!isDigit)(inputs); }
In addition to allowing these functions to become predicates they can now also be aliased, which allow you to make your functions simpler to understand:
import std.algorithm : any, all; import std.ascii : isDigit; void main() { alias isAnyDigit = any!isDigit; // less visual noise and a self-describing function string[] inputs = ["foo1", "bar2"]; bool allContainDigit = all!isAnyDigit(inputs); // easier to understand alias doAllContainDigits = all!isAnyDigit; // or wrap the entire algorithm into one symbol! assert( doAllContainDigits(["1", "a 1", "b 2"])); // self-describing code assert(!doAllContainDigits(["c", "a 1", "b 2"])); }
You can of course combine all and any in a number of combinations. For example, if you want to reverse the test and instead check whether any of the strings in the string array contain all digits, the code might look like the following:
import std.algorithm : any, all; import std.ascii : isDigit; void main() { alias areAllDigits = all!isDigit; alias areAnyIntegrals = any!areAllDigits; assert( areAnyIntegrals(["123", "456"])); assert( areAnyIntegrals(["abc", "123"])); // "123" is a number assert(!areAnyIntegrals(["abc", "def123"])); // "def123" is not really a number }
If on the other hand you want to ensure that all strings in the string array contain all digits, the could might look like the following:
import std.algorithm : any, all; import std.ascii : isDigit; void main() { alias areAllDigits = all!isDigit; alias allStringsDigits = all!areAllDigits; assert( allStringsDigits(["123", "456"])); assert(!allStringsDigits(["abc", "123"])); // "123" is a number, but "abc" is not }
- Allow std.algorithm.all to be used without a predicate.
You no longer need to pass a predicate if you want to match all items in a range which implicitly convert to true:
import std.algorithm; void main() { auto arr1 = [true, true, true]; assert( all(arr1)); // all values are true auto arr2 = [false, true, true]; assert(!all(arr2)); // all values are not true auto arr3 = [1, 2, 3]; assert( all(arr3)); // all values convert to true auto arr4 = [0, 2, 3]; assert(!all(arr4)); // all values do not convert to true }
- Add std.uni.byGrapheme and std.uni.byCodePoint.
Complementary higher-order ranges which enable range operations on graphemes:
import std.array : array; import std.range : retro; import std.string : text; import std.uni : byCodePoint, byGrapheme; void main() { string s = "noe\u0308l"; // noël // reverse it and convert the result back to UTF-8 string reverse = s.byGrapheme() .array() // Note: byGrapheme will support bidirectionality in the future .retro() .byCodePoint() .text(); assert(reverse == "le\u0308on"); // lëon }
Note that byGrapheme will support bidirectionality in the future, obviating the need for array in the above example. - Add support for any number of arguments to std.range.only.
only can now be used with more than one argument:
import std.algorithm : joiner; import std.range : equal, only; void main() { assert(only("one", "two", "three").joiner(" ").equal("one two three")); }
Additionally, only() is now a way to get an empty range.
Linker Changes
- Added /LARGEADDRESSAWARE to the Win32 Optlink linker.
When using the default Optlink linker on win32 (for linking 32-bit object files and executables), the /LARGEADDRESSAWARE option tells the linker that the application can handle addresses larger than 2 gigabytes. This is equivalent to Visual C's linker option of the same name since this is an operating-system feature that is enabled by setting a specific flag in the executable.
List of all bug fixes and enhancements in D 2.065:
DMD Compiler regressions
- Bugzilla 7782: [ICE] With wrong import syntax
- Bugzilla 9107: Value Range Analysis with uint and byte
- Bugzilla 9639: Recursive template instanciation segfault dmd
- Bugzilla 11078: Diagnostic for wrong RHS in property assign of a property group should improve
- Bugzilla 11321: Can't link _D6object15__T7reserveTyaZ7reserveFNaNbNeKAyamZm
- Bugzilla 11441: DMD halts compilation at semantic3
- Bugzilla 11447: Closure provide bogus values
- Bugzilla 11472: REGRESSION(2.064): dmd segfaults on wrong code instead of giving error
- Bugzilla 11487: dmd segfaults on writefln in nested template
- Bugzilla 11504: [CTFE] JSONValue cannot make in CTFE
- Bugzilla 11505: Bad error message: "opAssign [...] is annotated with @disable"
- Bugzilla 11508: [REG 2.064] Wrong code with -O on x86_64 for char comparisons
- Bugzilla 11513: [REG 2.064] Assertion in module.c
- Bugzilla 11525: REG(2.065): Error: 'a[] *= a[]' each element is not a scalar, it is a Complex!double
- Bugzilla 11553: dmd segfault with recursive template
- Bugzilla 11554: is(T == enum); produces an error if T is an enum defined with no members
- Bugzilla 11563: Module dependency cycle causes unrelated template instantiations to fail
- Bugzilla 11566: ICE with invalid array op
- Bugzilla 11596: Internal error: backend/cgcs.c 351
- Bugzilla 11610: Compiler core dumps on FreeBSD, compiles forever on Linux
- Bugzilla 11614: Error: this for _expand_field_0 needs to be type Tuple not type Foo
- Bugzilla 11626: [ICE] (mtype.c line 9718) With missing in ref type
- Bugzilla 11659: false positive goto skips initialization of variable error (skipping enum initialization)
- Bugzilla 11718: [REG2.065a] Unintended mangled names conflict of nested template structs
- Bugzilla 11723: Too many "integer overflow" errors
- Bugzilla 11730: associative array with Nullable!SysTime values: Called get on null Nullable!SysTime.
- Bugzilla 11751: [REG2.065a] Hex float exponents should be decimal
- Bugzilla 11755: Operator <>= and !<>= with arrays make internal error in e2ir
- Bugzilla 11767: doubly mixed-in struct "failed semantic analysis"
- Bugzilla 11776: [ICE] Assertion failure: 'tf->next == NULL' on line 119 in file 'mangle.c'
- Bugzilla 11777: [ICE] dmd memory corruption as Scope::pop frees fieldinit used also in enclosing
- Bugzilla 11805: Removal of Bool has critically broken expression evaluation
- Bugzilla 11818: Ternary operator not allowed in a value parameter anymore
- Bugzilla 11822: -de switch causees ICE with auto return and other stuff
- Bugzilla 11824: A stack variable escaping problem in CTFE Phobos code
- Bugzilla 11844: ICE(template.c:6643) Assertion failed: (td->semanticRun != PASSinit)
- Bugzilla 11849: Recursive enum causes segfault
- Bugzilla 11850: [ICE] Problem with filter with signed-unsigned array comparison
- Bugzilla 11852: RDMD broken on the Github HEAD
- Bugzilla 11854: Git-head does not build with Visual Studio
- Bugzilla 11863: std.conv.to!string(int/uint, radix) returns incorrect string
- Bugzilla 11868: ICE(template.c) on passing inout const argument as TemplateTupleParameter
- Bugzilla 11896: [REG2.066a] isVirtualMethod related GitHub HEAD regression (works with 2.064)
- Bugzilla 11914: Missed tuple unpacking in foreach for cartesianProduct
- Bugzilla 11919: GitHub HEAD regression for getAttributes trait (DMD CORE DUMP)
- Bugzilla 11922: [REG2.065a] ICE on nonexistent identifier in templated auto method
- Bugzilla 11924: inout Variadic Template Parameters
- Bugzilla 11925: [2.065] [REGRESSION] ICE in CompoundStatement::semantic
- Bugzilla 11930: Github regression -- Alias this not considered in is(T unused: U) matching
- Bugzilla 11931: Linkers "Symbol Undefined" again with dmd HEAD when -g specified
- Bugzilla 11941: Errors when appending to aggregate member array in CTFE
- Bugzilla 11956: dmd doesn't lookup /etc/dmd.conf
- Bugzilla 11963: Regression(2.065) ICE(parse.c) Parser crash
- Bugzilla 11965: Regression(2.064) Segfault on garbage
- Bugzilla 11966: Regression 2.065.b1: inout(const(char))[] doesn't convert to inout(char)[]
- Bugzilla 11967: Regression(2.065) ICE(parse.c) Parser crash
- Bugzilla 11980: startaddress pragma broken (DMD 2.061 regression)
- Bugzilla 11993: [REG] typeof(this) in constraint of member function template should reflect method qualifier
- Bugzilla 12002: Internal error: toir.c 181
- Bugzilla 12008: alias this and "unable to resolve forward reference" error
- Bugzilla 12010: [REG DMD2.065-b1] Undefined template symbols for static library linked with debug symbols
- Bugzilla 12016: implicit immutable upcast becomes null in CTFE
- Bugzilla 12017: DDoc leaves out the majority of documentation
- Bugzilla 12023: Regression 2.065-b2: template mixin fails within template class
- Bugzilla 12037: Link-failure with std.numeric.CustomFloat
- Bugzilla 12044: Invalid code gen causes segfault
- Bugzilla 12047: Regression (2.065 git-head): UDAs are not checked
- Bugzilla 12070: Variant opCall not static
- Bugzilla 12079: Internal error: backend/cod4.c 358 for associative array access
- Bugzilla 12080: Internal error: backend/symbol.c 1035 for invariant
- Bugzilla 12089: std.utf.validate and inout(char[]) failts to compile
- Bugzilla 12144: [REG DMD2.064] Unresolved xopEquals when referenced by dynamic array constructor
- Bugzilla 12158: ICE with .init of nonexisting selective import
- Bugzilla 12160: UDA related regressions
DMD Compiler bugs
- Bugzilla 235: goto & scope: cannot goto forward into different try block level
- Bugzilla 275: Undefined identifier in instances of templates with forward mixins
- Bugzilla 602: Compiler allows a goto statement to skip an initalization
- Bugzilla 899: structure field .offsetof property inaccessible in the scope
- Bugzilla 900: changing import order causes type mismatch
- Bugzilla 918: (D1 only): Template order matter, version block change something with typedef, and another template bug.
- Bugzilla 1687: "extern (C++) interface" and vtbl
- Bugzilla 1748: Wrong stringof for templated classes
- Bugzilla 2481: mixing field into anonymous struct inside class generates field overlapping vtable
- Bugzilla 2806: enum member cannot be forward referenced
- Bugzilla 2885: Silent forward reference bug using ReturnType
- Bugzilla 3013: Duplicate error message on calling a function with a type
- Bugzilla 3107: [meta] Property syntax
- Bugzilla 3226: -fPIC flag doesn't seem to work
- Bugzilla 3279: (D1 only) Confusing error message when comparing types
- Bugzilla 3307: Template alias default parameters aren't resolved properly
- Bugzilla 3753: ICE(eh.c): Related to exception handling and alloca.
- Bugzilla 3817: Array op: wrong error message
- Bugzilla 3834: forward reference in templated class
- Bugzilla 3903: Traits compiles as true for an array sum with wrong syntax
- Bugzilla 3970: Problem with cast -1.0L ==> uint/ulong
- Bugzilla 3991: Void initializers in unions considered overlapping
- Bugzilla 4145: cross alias namespace can't be resolve
- Bugzilla 4162: pass by alias offset problems
- Bugzilla 4983: [ICE] Stack overflow while initializing struct member with address of one of its methods
- Bugzilla 5569: 64 bit Dwarf symbolic debug info not recognized by gdb
- Bugzilla 5878: Forward reference in returning superclass from template using is() expression (Breaks std.traits.BaseTypeTuple)
- Bugzilla 6010: -fPIC is broken on freebsd/64
- Bugzilla 6382: edge case with static foreach
- Bugzilla 6439: [CTFE] union fields are initialized independently
- Bugzilla 6764: IFTI fails on typesafe variadic function over static array with non IntegerLiteral length
- Bugzilla 6796: Several __error with wrong enum definition
- Bugzilla 7077: (D1 only) mixin statements can invade the enclosing scope
- Bugzilla 7175: Zero-length static array .ptr is always null
- Bugzilla 7472: Cast from class to basic type not rejected during semantic
- Bugzilla 7645: ICE(e2ir.c) nested classes
- Bugzilla 7744: Forward reference in string mixin
- Bugzilla 7966: First template instantiation inside with results in Error 42: Symbol Undefined
- Bugzilla 8019: (D1 only) can't convert [] to int[]
- Bugzilla 8117: Cannot initialize struct member without default constructor
- Bugzilla 8179: ICE(e2ir.c) with failed fixed size array cast
- Bugzilla 8200: DMD segfault: template aliasing result of map
- Bugzilla 8244: cannot slice a type tuple with '[]' in locations where a type is valid
- Bugzilla 8255: [CTFE] ICE when passing 'ref' literal
- Bugzilla 8313: stack overflow on recursive ifti evaluation
- Bugzilla 8365: Static fixed size array of enums initialization fails
- Bugzilla 8396: wrong order of evaluation for tuple expansion in function arguments
- Bugzilla 8492: can't infer type in static assert
- Bugzilla 8511: Segfault with forward-referenced enum
- Bugzilla 8525: optimizer loops infinitely
- Bugzilla 8543: simd literals need better CTFE support
- Bugzilla 8581: Internal error: backend/cod1.c 1677 on structs with bitfields (when compile with release or optimize parameter)
- Bugzilla 8648: No error line number with incomplete template
- Bugzilla 8658: Passing large structs to function b value causes stack corruption
- Bugzilla 8664: Compiler causes stack overflow with recursive typedef and option -g
- Bugzilla 8711: ICE with initializing function pointer with array
- Bugzilla 8722: foreach triggers a floating point exception with multidimensional array of a dimension equal to 0
- Bugzilla 8735: ICE: Assertion failure: 't' on line 100 in file 'aliasthis.c'
- Bugzilla 8739: DDoc outputs wrong parameter name in delegate parameter list
- Bugzilla 8825: Wrong line number of error message
- Bugzilla 8903: Bad code for enum array members
- Bugzilla 8997: template instances omit symbol that may be used in other modules
- Bugzilla 9008: Another forward referencing bug
- Bugzilla 9050: Too early instantiation of template structs
- Bugzilla 9081: Modules shouldn't have a type
- Bugzilla 9212: Associative array foreach iteration with immutable key
- Bugzilla 9256: A purity-related error message in case of member access
- Bugzilla 9271: Forwarding lambda predicate with type inference causes segfault
- Bugzilla 9296: LITTLE_ENDIAN and BIG_ENDIAN are always defined on Linux
- Bugzilla 9301: using XMM.PSHUFD results in an internal compiler error
- Bugzilla 9356: -inline with inout and append generates wrong code
- Bugzilla 9459: Front-end does not detect invalid array operations
- Bugzilla 9466: Compiler crash with code-coverage generation with large files
- Bugzilla 9504: typeof does not look up properties correctly on template argument
- Bugzilla 9562: Built-in runtime properties should become error with Type.prop
- Bugzilla 9572: Missed wrong implicit integral conversion
- Bugzilla 9577: Crash on static array of function literals
- Bugzilla 9644: Spell checker gives silly suggestions for 1-2 character symbols
- Bugzilla 9662: Implement RDMD test suite
- Bugzilla 9690: cannot access to @disable'd symbol from inner function of another @disable'd
- Bugzilla 9741: undefined identifier with User Defined Attribute
- Bugzilla 9765: Error message with __error with struct literal dotvar expression
- Bugzilla 9807: with statement does not work with alias this
- Bugzilla 9831: Error message with failed lambda inference
- Bugzilla 9861: Spurious 'is used as type' error with failed template instantiation
- Bugzilla 9912: Wrong codegen when using tuple over member variable in more than one method
- Bugzilla 10207: Alias and @attributes: Assertion failure: '!udas' on line 3132 in file 'parse.c'
- Bugzilla 10224: core.simd ICE cgcv.c line 2162 when compiling with -g
- Bugzilla 10251: CTFE: Allow returning pointers to global static variables of known value
- Bugzilla 10259: ICE on invalid compile-time class instantiation
- Bugzilla 10312: compiler assert failure with ctfe on simd vector type
- Bugzilla 10313: inout constructor + IFTI + has indirections arg doesn't work
- Bugzilla 10329: Attributes not inferred for indirectly templated methods
- Bugzilla 10391: Segfault compiling on Mac OS 10.8
- Bugzilla 10459: align(16) does not work on Win64 with seperate compilation
- Bugzilla 10483: ICE(expression.c) .init of struct with block initialized 2D static array
- Bugzilla 10598: Using not-imported type - AssertFail: 'global.errors' line 6040 'template.c'
- Bugzilla 10632: [ICE](glue.c line 1227) With inlining and tuples
- Bugzilla 10635: Error: cannot use array to initialize S
- Bugzilla 10643: Refused const array struct field initialized with void
- Bugzilla 10747: Win64: warning about non-existing vc100.pdb
- Bugzilla 10770: is(T BASE==enum) with tag enum T - AssertFail:'type' line 428 declaration.c
- Bugzilla 10805: wrong error message for wrong delimited string
- Bugzilla 10883: [ICE] Internal error: ../ztc/cod4.c 358 when compiling with -inline
- Bugzilla 10905: [ICE](ctfeexpr.c line 355) with ulong2 in structs
- Bugzilla 10922: Compiler segfaults when using __traits(parent, {})
- Bugzilla 10926: Wrong expression printed when ternary operator used as lvalue
- Bugzilla 10927: Power of complex number causes an internal error
- Bugzilla 10938: ICE on recursive instantiation in opDispatch
- Bugzilla 11019: fwd reference : legal in C++, CT error in D (unable to resolve forward reference in definition)
- Bugzilla 11034: ICE: Assertion failed: (!scope), function toObjFile, file toobj.c, line 366.
- Bugzilla 11155: Wrong SIMD code generated (unaligned movaps)
- Bugzilla 11193: [ICE] String template argument mixed with variadic template arguments causes ICE
- Bugzilla 11198: Error messages for declaring a 'version' inside main() and other functions are unclear
- Bugzilla 11215: inout lose enclosing shared on resolution
- Bugzilla 11224: Inlining stops NRVO
- Bugzilla 11247: Error: typeof(i).sizeof is used as a type
- Bugzilla 11286: Impure dtor makes "cannot call impure function" error, although it won't actually be called.
- Bugzilla 11288: dmd assertion when assigning to (static) opDispatch
- Bugzilla 11297: [ICE](glue.c line 868) with a string concat in global enum lambda
- Bugzilla 11314: inline ice with tuple assignment and if/else again
- Bugzilla 11317: glue.c:1218: virtual unsigned int Type::totym(): Assertion 0 failed.
- Bugzilla 11322: ICE with -inline cgcs.c 221
- Bugzilla 11332: ICE(dt.c) and missing error when interpreting an unimplemented builtin
- Bugzilla 11371: core.simd and ctfe
- Bugzilla 11375: [profile+nothrow] Semantic 'no throw' error with -profile switch
- Bugzilla 11376: ICE on __traits(compiles, ...) with invalid array-op
- Bugzilla 11383: Some array casts incorrectly rejected in safe code
- Bugzilla 11385: XXX is a nested function and cannot be accessed from XXX
- Bugzilla 11394: NRVO should work for object field initialization in constructor
- Bugzilla 11406: ld.gold breaks switch table jumps
- Bugzilla 11425: Broken shadowing variable diagnostic
- Bugzilla 11427: anonymous unions break structs in @safe code
- Bugzilla 11445: adding double[string] causes crash
- Bugzilla 11479: template members ignore private attribute in ddoc
- Bugzilla 11484: [e2ir] Error in e2ir at cast to/from static array
- Bugzilla 11485: [e2ir] Error in e2ir at numeric/bool to class/interface cast
- Bugzilla 11489: Improper implicit cast to immutable.
- Bugzilla 11497: lambda in "static if"/"assert" prevent inlining of function
- Bugzilla 11518: DMD segfault on multiple template match
- Bugzilla 11534: [CTFE] inout + returning a pointer into a member array
- Bugzilla 11540: [ICE] CTFE segfault with try-catch-finally and goto
- Bugzilla 11552: Missing label is not caught during semantic
- Bugzilla 11562: Goto into or out of finally block is not caught during semantic
- Bugzilla 11565: [Optimizer] Zeroes out the higher 32bits of register in ?: expression
- Bugzilla 11587: Cannot compare AAs at compile time
- Bugzilla 11618: Internal Compiler Error
- Bugzilla 11627: [CTFE] cannot cast dchar to char at compile time on AA assignment
- Bugzilla 11629: [CTFE] crash on AA.rehash
- Bugzilla 11635: RDMD eats the -op flag when it should just pass through
- Bugzilla 11653: No error when forgetting break with range cases.
- Bugzilla 11656: property offsetof does not work with __vector fields
- Bugzilla 11661: Meaningless error: "a struct is not a valid initializer for a void function()"
- Bugzilla 11664: A function with a local static variable is unusable in CTFE
- Bugzilla 11689: deprecated local function does not work
- Bugzilla 11696: C++ incorrect static member mangling
- Bugzilla 11722: Qualifier-only casts should not invoke opCast
- Bugzilla 11726: ICE with ufcs on undefined identifier and opDispatch
- Bugzilla 11727: Repeated error message with using forward referenced enum as variable
- Bugzilla 11735: pragma(msg, ...) fails to print wstring, dstring
- Bugzilla 11745: Unittests retrieved by __traits(getUnitTests) can not be invoked if private.
- Bugzilla 11748: [ICE] function call as alias parameter of template gives ICE
- Bugzilla 11749: switch case fallthrough error is enabled with -w, but cannot be made informational warning
- Bugzilla 11750: ICE with debug info and empty #line Filespec
- Bugzilla 11756: Irrelevant variable name printing in CTFE error message
- Bugzilla 11769: Wrong line number in "matches both" error message
- Bugzilla 11785: Order of method/function declarations has an effect on compilation result.
- Bugzilla 11790: ICE(interpret.c): passing creation of array with type string as size to CTFE
- Bugzilla 11793: [ICE] Compiler runs out of memory with trivial program: class with own class member instance
- Bugzilla 11800: alias this matching incorrectly changes lvalue-ness
- Bugzilla 11802: Wrong vtbl order for extern(C++) classes with overloaded functions on win32
- Bugzilla 11813: Improve IFTI error diagnostic
- Bugzilla 11814: Unnecessary error messages "does not match ..." on IFTI failure
- Bugzilla 11843: Template instantiated twice: failed semantic analysis
- Bugzilla 11875: static if template type deduction causes infinite recursion with recursive alias this
- Bugzilla 11926: Segmentation fault when using const in an enum
- Bugzilla 11944: ICE(expression.c) Assertion f failed.
- Bugzilla 11968: ICE(expression.c) Crash when deleting __FILE__
- Bugzilla 11969: ICE(statement.c) When mixing in a array literal containing errors
- Bugzilla 11974: ICE(cast.c) Segfault with invalid assignment
- Bugzilla 11982: ICE(func.c) With function literal with no body
- Bugzilla 12038: alias this and &this cause ICE
- Bugzilla 12040: Compiler segfault with circular reference in variable type
- Bugzilla 12051: Wrong code with ?: resulting in char on x86-64
- Bugzilla 12095: Wrong code with -O -inline
DMD Compiler enhancements
- Bugzilla 3597: Need single source for parser and documentation grammar.
- Bugzilla 5109: some advise
- Bugzilla 5746: Make std.range.iota strongly pure
- Bugzilla 6930: combined type of immutable(T) and inout(T) should be inout(const(T))
- Bugzilla 9477: String (and array) comparisons are needlessly very slow
- Bugzilla 10199: labels cannot be used without a statement
- Bugzilla 11284: add -allinst compiler switch
- Bugzilla 11365: Allow D source file names to have no extension (or an arbitrary extension) when -run is used
- Bugzilla 11417: rotate with immediate not recognized by optimizer
- Bugzilla 11510: Relax restriction for overlapped pointer field access in safe code/during CTFE
- Bugzilla 11533: Compiler should allow to being nested for static local template functions
- Bugzilla 11546: string import dependency failure
- Bugzilla 11711: Add __traits(getAliasThis)
- Bugzilla 11759: Poor error message trying to use lowercase L in literal suffix.
- Bugzilla 11840: Show all errors of undefined identifier used in a line
Phobos regressions
- Bugzilla 1832: reading/writing an archive causes data loss; std.zip horribly broken
- Bugzilla 11309: std.concurrency: OwnerTerminated message doesn't work
- Bugzilla 11512: Can't build Phobos docs with win32 makefile
- Bugzilla 11527: JSONValue cannot set values through named fields
- Bugzilla 11528: appender: crash with -inline -O
- Bugzilla 11576: std.algorithm.remove!(SwapStrategy.unstable) overruns array bounds
- Bugzilla 11583: bigint bug
- Bugzilla 11591: std.typecons.Tuple -s with classes fails at runtime as associative array keys
- Bugzilla 11603: std.algorithm.canFind does not work when needle is 1-byte zero
- Bugzilla 11671: ctRegex broken
- Bugzilla 11684: SIGSEGV with ld.bfd version 2.22
- Bugzilla 11692: can't set file attributes for std.zip.ArchiveMember
- Bugzilla 11764: [REG2.065a]std.getopt broken
- Bugzilla 11831: std.zip no longer allows setting madeVersion field in zip file
- Bugzilla 11838: Missing emplace import for std.range.zip?
- Bugzilla 11853: Tuples fail "isAssignable"
- Bugzilla 11973: std/datetime.d(14647): Deprecation: function std.algorithm.canFind!(not).canFind!(immutable(dchar)[]).canFind is deprecated - Please use any instead
- Bugzilla 12024: [REG DMD2.065-b2] template instantiation for swap(SysTime, SysTime) fails
- Bugzilla 12071: Algebraic won't take delegate returning structure
- Bugzilla 12098: libcurl bad argument on handle null
- Bugzilla 12135: [AA] Format tail after associative array value is treated as separator if explicit separator is empty
- Bugzilla 12168: [REG2.065a] Add ref to array() and object() of JSONValue getters to add new element
Phobos bugs
- Bugzilla 1804: Severe GC leaks with repetitive array allocations
- Bugzilla 2162: Access violation when threads run closures
- Bugzilla 4301: BigInt * const(BigInt) doesn't work well
- Bugzilla 4673: Bug in std.string (isNumeric)
- Bugzilla 4874: std.numeric.dotProduct doesn't work with bigints
- Bugzilla 5280: to!FP(Hex float string) doesn't work well
- Bugzilla 5762: getopt: short option parameter read incorrectly when bundling enabled
- Bugzilla 5977: String splitting with empty separator
- Bugzilla 6730: std.algorithm.splitter conflicts with std.array.splitter
- Bugzilla 7069: Variant Doesn't Handle Const or Immutable Contents
- Bugzilla 7689: splitter() on ivalid UTF-8 sequences
- Bugzilla 8013: splitter() and split() give different results
- Bugzilla 8203: Use of std.regex.match() generates "not enough preallocated memory" error
- Bugzilla 8291: dirEntry cannot handle root directories + unhandled exception causes crash
- Bugzilla 8298: dirEntries special linux file in Home dir
- Bugzilla 8877: std.encoding.transcode is extremely slow
- Bugzilla 9528: std.array.appender can't append elements with const members
- Bugzilla 9645: std.algorithm.splitter on string with char as separator performs badly in certain situations
- Bugzilla 9823: Delegate accepting element not accepted in std.range.put
- Bugzilla 10569: std.traits: EnumMembers, isExpressionTuple, isTypeTuple & Largest balks at large input
- Bugzilla 10571: formattedWrite error with delegate and string
- Bugzilla 10710: shared phobos library doesn't work on all linux distributions
- Bugzilla 10864: [REG 2.064][PERFORMANCE] new Safe appender is slower than "~="
- Bugzilla 11005: std.xml does not encode attributes
- Bugzilla 11110: Variant.convertsTo doesn't work like isImplicitlyConvertible
- Bugzilla 11112: Unable to execute shell commands in different threads
- Bugzilla 11148: Can't implicitly convert const(BigInt) or immutable(BigInt) to BigInt
- Bugzilla 11180: Launching a process from a Windows GUI process using std.process.spawnProcess always fails
- Bugzilla 11403: functions in std.algo can't be used as pred
- Bugzilla 11459: std.container.Array bool constraint ambiguity
- Bugzilla 11568: can't compile std.stdio.rawWrite with -m64 in Windows
- Bugzilla 11600: to!BigInt(string) accepts non-numeric input
- Bugzilla 11606: Cannot instantiate Tuple of non printable
- Bugzilla 11617: std.uni.normalize doesn't compile
- Bugzilla 11652: Support numerical ^^ complex operations in std.complex
- Bugzilla 11681: std.datetime.IntervalRange.opAssign with non-ref parameter is required
- Bugzilla 11691: can't join pathSplitter with dirSeparator
- Bugzilla 11713: std.string munch() does not properly handle UTF strings.
- Bugzilla 11738: partialShuffle actually shuffles the entire input
- Bugzilla 11771: Unicode set intersection with char is broken
- Bugzilla 11775: std.regex should check for valid repetition range in assert mode
- Bugzilla 11780: RangeError in format for incomplete format specifier
- Bugzilla 11808: std.uni.CodepointSet('А', 'Я'+1, 'а', 'я'+1) asserts
- Bugzilla 11839: std.regex capture group names should allow numbers to be in them
- Bugzilla 11879: missing default User-Agent in std.net.curl
- Bugzilla 11884: std.container.Array lacks a constructor from an input range
- Bugzilla 12069: ctRegex is 3x slower then R-T ?
Phobos enhancements
- Bugzilla 3868: It would be nice to have a function which read a file lazily using a range
- Bugzilla 4859: Another File.byChunk()
- Bugzilla 4909: Two suggestions for std.algorithm.schwartzSort()
- Bugzilla 5611: back() and front() with ref return + opSlice() in sort() constraint
- Bugzilla 6986: SortedRange[x..$] fails with unidentified __dollar
- Bugzilla 8167: BigInt(BigInt(1)) too
- Bugzilla 9061: BigInt | BigInt, BigInt & int
- Bugzilla 11770: std.regex.Captures should be convertible to bool
- Bugzilla 11789: No setAttributes to complement getAttributes
- Bugzilla 11798: std.algorithm.all with no predicate too
Druntime regressions
- Bugzilla 11478: shared library on osx: worked in 2.062, fails in 2.063.2, still fails in 2.064
Druntime bugs
- Bugzilla 3454: Inconsistent flag setting in GC.realloc()
- Bugzilla 4809: Stack trace when throwing exception misses location of the throw statement
- Bugzilla 7508: float4 values aren't stored on initialisation
- Bugzilla 8301: Access violation when a big array is allocated
- Bugzilla 10701: [GC] segfault in GC
- Bugzilla 11806: Freeze in GC.collect() in in-contracts when multithreading is used
Optlink regressions
- Bugzilla 11559: Optlink crash with more than 2048 modules generated and debug info
Optlink bugs
- Bugzilla 2837: OPTLINK and LARGEADDRESSAWARE
- Bugzilla 3956: linker removes underscore from all exported symbols of a module but the first
- Bugzilla 6673: Map file contains broken lines on every 16,384 bytes
- Bugzilla 7634: optlink creates bad debug info for a large number of modules
Installer bugs
- Bugzilla 10246: Windows installer still downloads from ftp.digitalmars.com
- Bugzilla 11799: Incompatible argument types in create_dmd_release
Installer enhancements
- Bugzilla 10153: Beta releases should all have unique names
Website regressions
- Bugzilla 11449: Jump lists of phobos are in wrong order
Website bugs
- Bugzilla 5388: SList.insertFront has complexity O(log(n))
- Bugzilla 9734: setIntersection accepts only 2 ranges, but documentation says otherwise
- Bugzilla 10205: 'deprecated' '(' assignExpression ')' grammar is not documented
- Bugzilla 10206: User-defined attributes not documented well in language specification
- Bugzilla 10250: Grammar does not allow invariants in struct declarations
- Bugzilla 10514: Constructor declaration grammar is incorrect
- Bugzilla 11398: Language spec does not allow new eponymous template syntax
- Bugzilla 11579: dlang.org repo can't be built without git
- Bugzilla 11762: std.regex macro is not displayed/expanded properly
Website enhancements
- Bugzilla 11676: Add a link to D Wiki Sidebar to take users back to DLang.org
- Bugzilla 12087: Add Readme to dlang.org repository that explains how to contribute


String inflections define new methods on the String class to transform names for different purposes. For instance, you can figure out the name of a table from the name of a class.
'ScaleScore'.tableize # => "scale_scores"
Enable more predictable duck-typing on String-like classes. See
Object#acts_like?
.
# File lib/active_support/core_ext/string/behavior.rb, line 3 def acts_like_string? true end
If you pass a single Fixnum, returns a substring of one character at that position. The first character of the string is at position 0, the next at position 1, and so on. If a range is supplied, a substring containing characters at offsets given by the range is returned. In both cases, if an offset is negative, it is counted from the end of the string. Returns nil if the initial offset falls outside the string. Returns an empty string if the beginning of the range is greater than the end of the string.
str = "hello" str.at(0) #=> "h" str.at(1..3) #=> "ell" str.at(-2) #=> "l" str.at(-2..-1) #=> "lo" str.at(5) #=> nil str.at(5..-1) #=> ""
If a Regexp is given, the matching portion of the string is returned. If a String is given, that given string is returned if it occurs in the string. In both cases, nil is returned if there is no match.
str = "hello" str.at(/lo/) #=> "lo" str.at(/ol/) #=> nil str.at("lo") #=> "lo" str.at("ol") #=> nil
# File lib/active_support/core_ext/string/access.rb, line 27 def at(position) self[position] end
A string is blank if it’s empty or contains whitespaces only:
''.blank? # => true ' '.blank? # => true ' '.blank? # => true ' something here '.blank? # => false
# File lib/active_support/core_ext/object/blank.rb, line 91 def blank? self !~ /[^[:space:]]/ end
By default, camelize
converts strings to UpperCamelCase. If
the argument to camelize is set to :lower
then camelize
produces lowerCamelCase.
camelize
will also convert '/' to '::' which is useful for
converting paths to namespaces.
'active_record'.camelize # => "ActiveRecord" 'active_record'.camelize(:lower) # => "activeRecord" 'active_record/errors'.camelize # => "ActiveRecord::Errors" 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
# File lib/active_support/core_ext/string/inflections.rb, line 89 def camelize(first_letter = :upper) case first_letter when :upper ActiveSupport::Inflector.camelize(self, true) when :lower ActiveSupport::Inflector.camelize(self, false) end end
Create a class name from a plural table name like Rails does for table
names to models. Note that this returns a string and not a class. (To
convert to an actual class follow classify
with
constantize
.)
'egg_and_hams'.classify # => "EggAndHam" 'posts'.classify # => "Post"
Singular names are not handled correctly.
'business'.classify # => "Busines"
# File lib/active_support/core_ext/string/inflections.rb, line 189 def classify ActiveSupport::Inflector.classify(self) end
constantize
tries to find a declared constant with the name
specified in the string. It raises a NameError
when the name is not in CamelCase or is not initialized. See ActiveSupport::Inflector#constantize
'Module'.constantize # => Module 'Class'.constantize # => Class 'blargle'.constantize # => NameError: wrong constant name blargle
# File lib/active_support/core_ext/string/inflections.rb, line 65 def constantize ActiveSupport::Inflector.constantize(self) end
Replaces underscores with dashes in the string.
'puni_puni'.dasherize # => "puni-puni"
# File lib/active_support/core_ext/string/inflections.rb, line 125 def dasherize ActiveSupport::Inflector.dasherize(self) end
Removes the rightmost segment from the constant expression in the string.
'Net::HTTP'.deconstantize # => "Net" '::Net::HTTP'.deconstantize # => "::Net" 'String'.deconstantize # => "" '::String'.deconstantize # => "" ''.deconstantize # => ""
See also demodulize
.
# File lib/active_support/core_ext/string/inflections.rb, line 148 def deconstantize ActiveSupport::Inflector.deconstantize(self) end
Removes the module part from the constant expression in the string.
'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections" 'Inflections'.demodulize # => "Inflections"
See also deconstantize
.
# File lib/active_support/core_ext/string/inflections.rb, line 135 def demodulize ActiveSupport::Inflector.demodulize(self) end
# File lib/active_support/core_ext/string/encoding.rb, line 4 def encoding_aware? ActiveSupport::Deprecation.warn 'String#encoding_aware? is deprecated' true end
The inverse of String#include?
. Returns true if the string
does not include the other string.
"hello".exclude? "lo" #=> false "hello".exclude? "ol" #=> true "hello".exclude? h #=> false
# File lib/active_support/core_ext/string/exclude.rb, line 8 def exclude?(string) !include?(string) end
Returns the first character. If a limit is supplied, returns a substring from the beginning of the string until it reaches the limit value. If the given limit is greater than or equal to the string length, returns self.
str = "hello" str.first #=> "h" str.first(1) #=> "h" str.first(2) #=> "he" str.first(0) #=> "" str.first(6) #=> "hello"
# File lib/active_support/core_ext/string/access.rb, line 75 def first(limit = 1) if limit == 0 '' elsif limit >= size self else to(limit - 1) end end
Creates a foreign key name from a class name.
separate_class_name_and_id_with_underscore
sets whether the
method should put ‘_’ between the name and ‘id’.
'Message'.foreign_key # => "message_id" 'Message'.foreign_key(false) # => "messageid" 'Admin::Post'.foreign_key # => "post_id"
# File lib/active_support/core_ext/string/inflections.rb, line 209 def foreign_key(separate_class_name_and_id_with_underscore = true) ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) end
Returns a substring from the given position to the end of the string. If the position is negative, it is counted from the end of the string.
str = "hello" str.from(0) #=> "hello" str.from(3) #=> "lo" str.from(-2) #=> "lo"
You can mix it with to
method and do fun things like:
str = "hello" str.from(0).to(-1) #=> "hello" str.from(1).to(-2) #=> "ell"
# File lib/active_support/core_ext/string/access.rb, line 44 def from(position) self[position..-1] end
# File lib/active_support/core_ext/string/output_safety.rb, line 191 def html_safe ActiveSupport::SafeBuffer.new(self) end
Capitalizes the first word, turns underscores into spaces, and strips
‘_id’. Like titleize
, this is meant for creating pretty
output.
'employee_salary'.humanize # => "Employee salary" 'author_id'.humanize # => "Author"
# File lib/active_support/core_ext/string/inflections.rb, line 198 def humanize ActiveSupport::Inflector.humanize(self) end
Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default is set, otherwise converts String to a Time via #to_time
# File lib/active_support/core_ext/string/zones.rb, line 6 def in_time_zone(zone = ::Time.zone) if zone ::Time.find_zone!(zone).parse(self) else to_time end end
Indents the lines in the receiver:
"def some_method some_code end ".indent(2) # => def some_method some_code end
The second argument, indent_string
, specifies which indent
string to use. The default is nil
, which tells the method to
make a guess by peeking at the first indented line, and fallback to a space
if there is none.
" foo".indent(2) # => " foo" "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar" "foo".indent(2, "\t") # => "\t\tfoo"
While indent_string
is typically one space or tab, it may be
any string.
The third argument, indent_empty_lines
, is a flag that says
whether empty lines should be indented. Default is false.
"foo\n\nbar".indent(2) # => " foo\n\n bar" "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
# File lib/active_support/core_ext/string/indent.rb, line 40 def indent(amount, indent_string=nil, indent_empty_lines=false) dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)} end
Same as indent
, except it indents the receiver in-place.
Returns the indented string, or nil
if there was nothing to
indent.
# File lib/active_support/core_ext/string/indent.rb, line 5 def indent!(amount, indent_string=nil, indent_empty_lines=false) indent_string = indent_string || self[/^[ \t]/] || ' ' re = indent_empty_lines ? /^/ : /^(?!$)/ gsub!(re, indent_string * amount) end
Wraps the current string in the ActiveSupport::StringInquirer
class, which gives you a prettier way to test for equality.
env = 'production'.inquiry env.production? # => true env.development? # => false
# File lib/active_support/core_ext/string/inquiry.rb, line 10 def inquiry ActiveSupport::StringInquirer.new(self) end
# File lib/active_support/core_ext/string/multibyte.rb, line 38 def is_utf8? case encoding when Encoding::UTF_8 valid_encoding? when Encoding::ASCII_8BIT, Encoding::US_ASCII dup.force_encoding(Encoding::UTF_8).valid_encoding? else false end end
Returns the last character of the string. If a limit is supplied, returns a substring from the end of the string until it reaches the limit value (counting backwards). If the given limit is greater than or equal to the string length, returns self.
str = "hello" str.last #=> "o" str.last(1) #=> "o" str.last(2) #=> "lo" str.last(0) #=> "" str.last(6) #=> "hello"
# File lib/active_support/core_ext/string/access.rb, line 95 def last(limit = 1) if limit == 0 '' elsif limit >= size self else from(-limit) end end
mb_chars
is a multibyte safe proxy for string methods.
It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy class. If the proxy class doesn’t respond to a certain method, it’s forwarded to the encapsulated string.
name = 'Claus Müller' name.reverse # => "rell??M sualC" name.length # => 13 name.mb_chars.reverse.to_s # => "rellüM sualC" name.mb_chars.length # => 12
All the methods on the Chars proxy which normally return a string will return a Chars object. This allows method chaining on the result of any of these methods.
name.mb_chars.reverse.length # => 12
The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing
between String and Char work like expected. The
bang! methods change the internal string representation in the Chars
object. Interoperability problems can be resolved easily with a
to_s
call.
For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
# File lib/active_support/core_ext/string/multibyte.rb, line 34 def mb_chars ActiveSupport::Multibyte.proxy_class.new(self) end
Replaces special characters in a string so that it may be used as part of a ‘pretty’ URL.
class Person def to_param "#{id}-#{name.parameterize}" end end @person = Person.find(1) # => #<Person id: 1, name: "Donald E. Knuth"> <%=<EMAIL_ADDRESS>person_path) %> # => Donald E. Knuth
# File lib/active_support/core_ext/string/inflections.rb, line 165 def parameterize(sep = '-') ActiveSupport::Inflector.parameterize(self, sep) end
Returns the plural form of the word in the string.
If the optional parameter count
is specified, the singular
form will be returned if count == 1
. For any other value of
count
the plural will be returned.
If the optional parameter locale
is specified, the word will
be pluralized as a word of that language. By default, this parameter is set
to :en
. You must define your own inflection rules for
languages other than English.
'post'.pluralize # => "posts" 'octopus'.pluralize # => "octopi" 'sheep'.pluralize # => "sheep" 'words'.pluralize # => "words" 'the blue mailman'.pluralize # => "the blue mailmen" 'CamelOctopus'.pluralize # => "CamelOctopi" 'apple'.pluralize(1) # => "apple" 'apple'.pluralize(2) # => "apples" 'ley'.pluralize(:es) # => "leyes" 'ley'.pluralize(1, :es) # => "ley"
# File lib/active_support/core_ext/string/inflections.rb, line 31 def pluralize(count = nil, locale = :en) locale = count if count.is_a?(Symbol) if count == 1 self else ActiveSupport::Inflector.pluralize(self, locale) end end
safe_constantize
tries to find a declared constant with the
name specified in the string. It returns nil when the name is not in
CamelCase or is not initialized. See ActiveSupport::Inflector#safe_constantize
'Module'.safe_constantize # => Module 'Class'.safe_constantize # => Class 'blargle'.safe_constantize # => nil
# File lib/active_support/core_ext/string/inflections.rb, line 76 def safe_constantize ActiveSupport::Inflector.safe_constantize(self) end
The reverse of pluralize
, returns the singular form of a word
in a string.
If the optional parameter locale
is specified, the word will
be singularized as a word of that language. By default, this parameter is
set to :en
. You must define your own inflection rules for
languages other than English.
'posts'.singularize # => "post" 'octopi'.singularize # => "octopus" 'sheep'.singularize # => "sheep" 'word'.singularize # => "word" 'the blue mailmen'.singularize # => "the blue mailman" 'CamelOctopi'.singularize # => "CamelOctopus" 'leyes'.singularize(:es) # => "ley"
# File lib/active_support/core_ext/string/inflections.rb, line 54 def singularize(locale = :en) ActiveSupport::Inflector.singularize(self, locale) end
Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.
Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
%Q{ Multi-line string }.squish # => "Multi-line string" " foo bar \n \t boo".squish # => "foo bar boo"
# File lib/active_support/core_ext/string/filters.rb, line 11 def squish dup.squish! end
Performs a destructive squish. See #squish.
# File lib/active_support/core_ext/string/filters.rb, line 16 def squish! gsub!(/\A[[:space:]]+/, '') gsub!(/[[:space:]]+\z/, '') gsub!(/[[:space:]]+/, ' ') self end
Strips indentation in heredocs.
For example in
if options[:usage] puts <<-USAGE.strip_heredoc This command does such and such. Supported options are: -h This message ... USAGE end
the user would see the usage message aligned against the left margin.
Technically, it looks for the least indented line in the whole string, and removes that amount of leading whitespace.
# File lib/active_support/core_ext/string/strip.rb, line 22 def strip_heredoc indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0 gsub(/^[ \t]{#{indent}}/, '') end
Creates the name of a table like Rails does for models to table names. This
method uses the pluralize
method on the last word in the
string.
'RawScaledScorer'.tableize # => "raw_scaled_scorers" 'egg_and_ham'.tableize # => "egg_and_hams" 'fancyCategory'.tableize # => "fancy_categories"
# File lib/active_support/core_ext/string/inflections.rb, line 175 def tableize ActiveSupport::Inflector.tableize(self) end
Capitalizes all the words and replaces some characters in the string to
create a nicer looking title. titleize
is meant for creating
pretty output. It is not used in the Rails internals.
titleize
is also aliased as titlecase
.
'man from the boondocks'.titleize # => "Man From The Boondocks" 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
# File lib/active_support/core_ext/string/inflections.rb, line 107 def titleize ActiveSupport::Inflector.titleize(self) end
Returns a substring from the beginning of the string to the given position. If the position is negative, it is counted from the end of the string.
str = "hello" str.to(0) #=> "h" str.to(3) #=> "hell" str.to(-2) #=> "hell"
You can mix it with from
method and do fun things like:
str = "hello" str.from(0).to(-1) #=> "hello" str.from(1).to(-2) #=> "ell"
# File lib/active_support/core_ext/string/access.rb, line 61 def to(position) self[0..position] end
Converts a string to a Date value.
"1-1-2012".to_date #=> Sun, 01 Jan 2012 "01/01/2012".to_date #=> Sun, 01 Jan 2012 "2012-12-13".to_date #=> Thu, 13 Dec 2012 "12/13/2012".to_date #=> ArgumentError: invalid date
# File lib/active_support/core_ext/string/conversions.rb, line 42 def to_date ::Date.parse(self, false) unless blank? end
Converts a string to a DateTime value.
"1-1-2012".to_datetime #=> Sun, 01 Jan 2012 00:00:00 +0000 "01/01/2012 23:59:59".to_datetime #=> Sun, 01 Jan 2012 23:59:59 +0000 "2012-12-13 12:50".to_datetime #=> Thu, 13 Dec 2012 12:50:00 +0000 "12/13/2012".to_datetime #=> ArgumentError: invalid date
# File lib/active_support/core_ext/string/conversions.rb, line 52 def to_datetime ::DateTime.parse(self, false) unless blank? end
Converts a string to a Time value. The
form
can be either :utc or :local (default :local).
The time is parsed using Time.parse method. If form
is :local,
then the time is in the system timezone. If the date part is missing then
the current date is used and if the time part is missing then it is assumed
to be 00:00:00.
"13-12-2012".to_time # => 2012-12-13 00:00:00 +0100 "06:12".to_time # => 2012-12-13 06:12:00 +0100 "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100 "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100 "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 05:12:00 UTC
# File lib/active_support/core_ext/string/conversions.rb, line 18 def to_time(form = :local) parts = Date._parse(self, false) return if parts.empty? now = Time.now time = Time.new( parts.fetch(:year, now.year), parts.fetch(:mon, now.month), parts.fetch(:mday, now.day), parts.fetch(:hour, 0), parts.fetch(:min, 0), parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), parts.fetch(:offset, form == :utc ? 0 : nil) ) form == :utc ? time.utc : time.getlocal end
Truncates a given text
after a given length
if
text
is longer than length
:
'Once upon a time in a world far far away'.truncate(27) # => "Once upon a time in a wo..."
Pass a string or regexp :separator
to truncate
text
at a natural break:
'Once upon a time in a world far far away'.truncate(27, separator: ' ') # => "Once upon a time in a..." 'Once upon a time in a world far far away'.truncate(27, separator: /\s/) # => "Once upon a time in a..."
The last characters will be replaced with the :omission
string
(defaults to “…”) for a total length not exceeding length
:
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)') # => "And they f... (continued)"
# File lib/active_support/core_ext/string/filters.rb, line 41 def truncate(truncate_at, options = {}) return dup unless length > truncate_at options[:omission] ||= '...' length_with_room_for_omission = truncate_at - options[:omission].length stop = if options[:separator] rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission else length_with_room_for_omission end "#{self[0...stop]}#{options[:omission]}" end
The reverse of camelize
. Makes an underscored, lowercase form
from the expression in the string.
underscore
will also change '::' to '/' to convert namespaces
to paths.
'ActiveModel'.underscore # => "active_model" 'ActiveModel::Errors'.underscore # => "active_model/errors"
# File lib/active_support/core_ext/string/inflections.rb, line 118 def underscore ActiveSupport::Inflector.underscore(self) end


var outerValue = 'ninja'; var later; function outerFunction() { var innerValue = 'samurai'; function innerFunction() { assert(outerValue,"I can see the ninja."); assert(innerValue,"I can see the samurai"); assert(lt,"later join"); } later = innerFunction; } var lt = 'later join'; outerFunction(); later(); #1 Declares an empty variable #2 Declares a value inside the function #3 Declares an inner function #4 Invokes the outer function #5 Invokes the inner function 1. Function parameters are included in the closure of that function. 2. All variables in an outer scope, even those declared after the function declaration, are included. 3. Within the same scope, variables not yet defined cannot be forward referenced.


{% extends "layout.html" %}
{% block body %}
{% if warning %}
IMPORTANT: This is a test system only and should not be used in production.
{% endif %}
This system is used to verify someone. For more information, see the help page.


Methods
-
list( options ) → {Promise.<Array.<Object>>}
-
Description
Gets the list of apps installed into a courseParameters
Name Type Description options
object object containing all arguments Name Type Attributes Description courseId
number Canvas course Id to query excludeParents
boolean <optional> If true, excludes tools installed in all accounts above the current context Returns
Details
-
get( options ) → {Promise.<Object>}
-
Description
Gets info on a single LTI toolParameters
Name Type Description options
object object containing all arguments Name Type Description courseId
number Canvas course Id appId
number The LTI app Id to get Returns
Details
-
add( options ) → {Promise.<Object>}
-
Description
Adds an LTI app to a Canvas courseParameters
Name Type Description options
object object containing all arguments Name Type Attributes Description courseId
number Canvas course Id to install into name
string The app name (for settings app list) key
string Installation consumer key secret
string Installation consumer secret xml
string XML configuration file, standard LTI format description
string <optional> A human-readable description of the app launchPrivacy
string <optional> 'public' by default Returns
Details
-
remove( options ) → {Promise.<Object>}
-
Description
Removes an LTI app from a Canvas courseParameters
Name Type Description options
object object containing all arguments Name Type Description courseId
number Canvas course Id to remove app from appId
number The LTI app Id to remove Returns
Details
-
getMetadata( options ) → {Promise.<Object>}
-
Description
Gets the metadata for an LTI app in a course. Note: this endpoint requires that the app have a custom parameter called 'metadataId' with an identifier that we will use to refer to the metadata. If each installation of an app will have its own metadata, each installation should have a different metadataId. If all installations share the same metadata, they should all have the same metadataId. When getting metadata, we return the metadata for the first app we find that has this metadataIdParameters
Name Type Description options
object object containing all arguments Name Type Description courseId
number Canvas course Id that holds the app metadataId
number metadata identifier (see endpoint description) Returns
Details
-
updateMetadata( options ) → {Promise.<Array.<Object>>}
-
Description
Updates the metadata for an LTI app in a course. Note: this endpoint requires that the app have a custom parameter called 'metadataId' with an identifier that we will use to refer to the metadata. If each installation of an app will have its own metadata, each installation should have a different metadataId. If all installations share the same metadata, they should all have the same metadataId. When updating metadata, we update the metadata for all apps with the given metadataIdParameters
Name Type Description options
object object containing all arguments Name Type Attributes Default Description courseId
number Canvas course Id that holds the app metadataId
number metadata identifier (see endpoint description) metadata
object <optional> {} json metadata object Returns
Details


Guys,
I had working platform Raspi+HDD+SD+hub+Jeelink (via USB). I was completely satisfied with that including new great functionality of My Electric module. As I had a problem with reading data from EMONCMS via json (it rerurned 21 hourly values instead of 24 for last 24 hours), I have updated via git pull to ver 8.0.9. Everthing was OK, it returned now correctly 24 values. But after system reboot it stopped communication with Jeelink and inputs are not updated more. It seems to me, that rfm12piphp service is stopped and I dont know how to get it working back. I tried
sudo service rfm12piphp restart
but situation didnt change. Inputs sent from another node via ethernet into my emoncms are update correctly, but inputs updated via RFM12 (via USB jeeelink) are dead.
Does anyone has an idea, what has been changed in system setting during update from 8.0.8 to 8.0.9 and could be causing my problem?
Re: Not updated inputs after update to 8.0.9
The latest version of rfm12piphp in emoncms/Modules/raspberrypi from github has RPI_BIN="/usr/share/emoncms/www/Modules/raspberrypi/raspberrypi_run.php" on line 35 which I think may be causing the problem. The update to the Debian packaged version seems to be causing a problem installing via Git.
I've been trying to setup a fresh git install and had to change it back to the old version which had RPI_BIN="var/www/emoncms/Modules/raspberrypi/raspberrypi_run.php" in order to get the interface running.
Re: Not updated inputs after update to 8.0.9
I tried to reinstall whole raspberry platform image to my HDD. In settings of image from Feb 23rd everything works. Even if after "git pull" update. But if I reboot it then for any reason, communication with Jeelink RFM12 stops.
I checked my rfm12piphp after that update and it seems to be unchanged by update process. And on line 35 is written
RPI_BIN="var/www/emoncms/Modules/raspberrypi/raspberrypi_run.php"
update to v 8.0.9 modified probably something more yet...
Re: Not updated inputs after update to 8.0.9
There is also a copy at /etc/init.d/rfm12piphp used during start up, you could check the path in that file also.
Paul
Re: Not updated inputs after update to 8.0.9
I obviously missed that path when backing out the debian changes from the repos, sorry.
It should be as-is for the serving-git-repos approach then patched in the .deb file - I'll try to fix this over the weekend.
IMO the OEM gateway is the future for bridging the rfm12pi to emoncms, but that doesn't mean we should leave the integrated module broken... apologies.
Re: Not updated inputs after update to 8.0.9
Just to add: you probably did a git pull and didn't restart the rfm12piphp script for some time, so you thought it worked, but that was only because the daemon was still in memory. First time you had to restart your Pi it crapped out trying to reload.
This is one of the structural issues with the rfm12piphp approach that I really dislike, as I lost a chunk of data myself making a bad assumption about this.
Re: Not updated inputs after update to 8.0.9
I checked that copy in /etc/init.d, but that path is also correct.
Radek
Re: Not updated inputs after update to 8.0.9
yes, exactly, I didnt restart system for a few days, but yesterday evening we had short dropout of electricity supply due storm, so it restarted itsellf.
To be honest, I would use OEM gateway, but Im little bit confused, how it works, especially its co-existence with rfm12piphp daemon. I need stable system and I dont know, which one of these two solutions is better and why and how to set it up properly. Is there any info resource covering this area?
At this moment I guess, it is best solution for me to downgrade back to that image from Feb 23rd, as it works reliably. Or would you recommend me another scenario?
Re: Not updated inputs after update to 8.0.9
The Feb 23rd image is probably your best solution at present.
I've just tried fresh installs from git and from apt for the Rpi and couldn't get either to work. The git version had problems loading rfm12pi due to file locations. The apt version has the rfm12pi status as running but no inputs can be created.
Re: Not updated inputs after update to 8.0.9
@ ngbod - when installing the apt version from fresh did did you edit /boot/cmdline.txt and /etc/inittab ? http://openenergymonitor.org/emon/node/4777#comment-20231
Paul
Re: Not updated inputs after update to 8.0.9
@ rbreuss - You say "I checked that copy in /etc/init.d, but that path is also correct." have you edited or overwritten it at any point? after changes you need to update-rc, probably best to go over these 2 steps again just to be sure
sudo chmod 755 /etc/init.d/rfm12piphp
sudo update-rc.d rfm12piphp defaults
You could revert to the old image or the apt version definitely works ok once serial access is sorted(/boot/cmdline.txt and /etc/inittab edits)
Paul
Re: Not updated inputs after update to 8.0.9
Ahhh! something else I've just thought of there are also copies of rfm12piphp & rfm12pi_run.php located in .../Modules/node, I never did find out why but I do recall wondering why there where there and the ..../nodes/rfm12piphp was used rather than the .../raspberrypi/rfm12piphp for some reason so worth checking there as well.
Re: Not updated inputs after update to 8.0.9
Thanks Paul, my apt install is now working.
I checked and boot/cmdline.txt had been edited but inittab hadn't. I edited it and rebooted and all now seems well.
I remember editing them on the previous git install but there is no mention of these edits in the pkg-emoncms readme which I followed for the apt install.
Re: Not updated inputs after update to 8.0.9
Paul,
I have very basic knowledge of LINUX administration and configuration. I just copied packaged FEB 23rd image to HDD (and to SD of course) and run "git pull" update in /var/www/emoncms folder. Before update it works, after update not. I didnt edit rfm12piphp file as I have no reason and mainly not knowledge enough to do it.  Ver 8.0.9 is much better than that original one. Im learning how to take care for my LINUX system, but it goes slowly and each hint from experienced colleague is valuable for me.
Radek
Re: Not updated inputs after update to 8.0.9
@ngbod - glad it worked, yes the readme does need updating and I sure it will be shortly as these omissions only came to light quite recently.
@Radek - How much data have you collected? if you want a later version than the feb hdd image (which I'm sure you do) the best way forward would probably be to start with a fresh raspbian image and install using the apt method, it is so much easier and definitely works well (aside from the previously mentioned readme ommision).
There are various ways to do it but if you do not have much data apt is the way to go, around 10mins from fresh raspbian image to a fully functioning emoncms install that you can then continue to update regularly using apt-get update.
Paul
Re: Not updated inputs after update to 8.0.9
Thanks for a new, promising direction for me, Paul! I have no important data, just a few days from testing run. We can forget them.
OK,now I have a fresh installation of Feb 23 Raspi image at my HDD. And now, how to process that update via apt method? I never did it before, so I have zero knowledge at this point. Is there any step by step tutorial available at this forum?
Radek
Re: Not updated inputs after update to 8.0.9
I would start a fresh by downloading the latest raspbian image and put that image on a SD card and also the hdd.
From there we can just do a couple of things to set up the hdd (that's the trickier bit) and then use apt-get to install emoncms
read http://openenergymonitor.org/emon/node/4384 while your downloading image, although 5 commands is just emoncms, the rfm2pi module isn't that many more :-)
Paul
Re: Not updated inputs after update to 8.0.9
That's a completely new world for me. I'm going to dive in and we will see. I will let you know, how I'm doing there.
My big thanks for this moment.
Radek
Re: Not updated inputs after update to 8.0.9
Soooo, I downloaded that raspian image a copied it to SD. There was no any bit of code to be put to HD.
So, I have image on SD, i got in via SSH. Steps descibed in installation cookbook worked and it seems to be installed. But just on SD. How to get from SD to HD installation?
Re: Not updated inputs after update to 8.0.9
Just as an aside - if anyone would like to submit a pull request to improve any of the documentation on my pkg_* repositories (or indeed the packaging itself) then please feel free!
https://github.com/Dave-McCraw/pkg-emoncms
https://github.com/Dave-McCraw/pkg-emoncms-module-rfm12pi
You can just go to the readme.md file and hit the edit button you know, github will pretty much take care of the rest :-)
Re: Not updated inputs after update to 8.0.9
@rbreuss, the raspian image will indeed just be on your SD card. I'm not sure of the steps required to get the non-boot partitions onto the HDD, but I presume Trystan or Glyn can point us at some guidance on this (I can't seem to find a build guide for the HDD, perhaps because it's just a little late on a Friday night :)
Re: Not updated inputs after update to 8.0.9
The easiest way is to put the image on BOTH the sd and the hdd, boot up on the sd and then edit the hdd to prepare it to boot to, so first you need to give the hdd a unique uuid and then mount the hdd
sudo tune2fs -U random -L hdd /dev/sda2
sudo mkdir /media/hdd
sudo mount /dev/sda2 /media/hdd
then edit the hdd's fstab
sudo nano /media/hdd/etc/fstab
change " /dev/mmcblk0p2 " to " /dev/sda2 " and Ctrl+x, y, enter,
while we are here just edit the inittab (the bit that's missing above)
sudo nano /media/hdd/etc/inittab
edit the very last line by adding a hash so it reads " # T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100 "
edit the cmdline.txt and reboot (the next 2 lines are 1 line wrapped be sure it is entered as 1 line "sudo" to "txt'")
sudo sh -c 'echo "dwc_otg.lpm_enable=0 console=tty1 root=/dev/sda2 rootfstype=ext4 elevator=deadline rootwait" > /boot/cmdline.txt'
sudo shutdown -r now
should now boot up to the hdd so add the repo to sources list, update and install (next 2 lines as one line again)
sudo sh -c "echo 'deb http://emon-repo.s3.amazonaws.com wheezy unstable' >> /etc/apt/sources.list"
sudo apt-get update
sudo apt-get -y --force-yes install emoncms emoncms-module-event emoncms-module-rfm12pi
you will get asked a series of questions about mysql and emoncms passwords
sudo a2ensite emoncms
sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart
sudo service rfm12piphp start
go to http;//IP.ADD.OF.PI/emoncms and register a user and with any luck you're in.
Paul
Re: Not updated inputs after update to 8.0.9
Dave - I wasn't sure if the readme was to be updated yet as the discussion about automating the process v separate rfm2pi instructions wasn't complete.
I think some hdd image instructions or blank download image maybe a great help, case in hand as an example. I thought I would try this as a complete a to z install and if it is complete it can be used to build a readme maybe. (I only say if because this is from memory I really should make notes as I do an istall from absolute fresh ie single downloaded image)
Paul
Re: Not updated inputs after update to 8.0.9
Oh, thats really a complex cookbook (In Middle Ages of IT, 30 years ago I was mounting first disk storage into mainframe computers with paper punched tape OS by similar sequences of "secret" commands :-)). THANKS Paul, for your open approach and Im going to try that step by step.
Radek
Re: Not updated inputs after update to 8.0.9
I confirm, it works! Now I have fresh installation of emoncms 8.0.9. Great tutorial Paul!
Let me to ask you a few additional questions:
1) If I reboot my new system now, all of the services will start automaticaly? Or should I start
sudo service rfm12piphp start manually?
2) If I will process further updates, which steps of your tutorial I should use?
Radek
Re: Not updated inputs after update to 8.0.9
Everything should work correctly after a reboot, I would recommend trying it while you are setting up /testing as you don't want to come home one day and find several hour data missing and not know why following a momentary power outage or similar.
In future when you use sudo apt-get update && sudo apt-get upgrade emoncms will get updated along with everything else.
As more modules become available in apt packaging you can install them with apt-get install as well but there maybe other steps also and that will be documented with each module.
The second partition of your sdcard still holds a redundant copy of raspbian, you could copy just the boot partition to a smaller sdcard if you wanted to free up this sdcard or if not just leave it there and if ever you have an issue with your "hdd" version you can whip out the sdcard edit the /boot/cmdline.txt file on windows by changing "/dev/sda2" to "/sda/mmcblk0p2" and pop it back it the pi to boot into the sdcard image and explore / fix your hdd image.
There are tidier methods to do this but this is by far the easiest way without another linux machine.
Paul
Re: Not updated inputs after update to 8.0.9
Realy good job, Paul! Is works great, everything I tested till now is OK. Nice to meet guy, which knows, whats the game about.
As new modules become available, where I will find them? Is there any central repository?
Only unusal behavior, my new system has now - before at old emoncms installation based on standard Raspi/HDD/SD/Emoncms package I was able to modify any file via WINSCP editor. Now, any modification this way is refused due "permission denied". When I modify file via "sudo nano...", modification is accepted, but any modif via WINSCP is refused. Why? Is there any wrong setup of access permission in my new setup?
Re: Not updated inputs after update to 8.0.9
I have set up a 2nd Pi for developement/testing as above and I too am experiencing the same problem with WINSCP as the post above (and yes I do have Shell set to sudo su - in the advanced site settings)
Re: Not updated inputs after update to 8.0.9
I had never used WinSCP before today I have just tried it to recreate your issue and found it really quite good, I found the same situation and the solution is to enable a root user.
In normal use a raspberry pi user can get temporary root access by prefixing command with "sudo" WinSCP isn't able to prefix command to get root access, You can however log in as "root" if you set up the root user password on pi first.
sudo passwd
enter a password and confirm.
You can now open a session in WinSCP logging into pi using the username root and the password you just set up.
(SSH & normal logging in as your usual user (pi) and using sudo will still work exactly as as before.)
To revoke this additional "root" user, whilst logged in as your usual user (pi)
sudo passwd -l root
and all is back as it was :-)
Paul
Re: Not updated inputs after update to 8.0.9
Your remedy works again to 100%. You are great tutor. Thanks, Paul.
Radek
Re: Not updated inputs after update to 8.0.9
@ph66;@rbreuss;
thanks for the guide, I am not an expert in computer science, I wanted to ask, when the installation requires a username and password for mysql, I can insert any data or not. When ask me the localhost, I have to enter the IP address of raspberry or leave "localhost".
sorry for my english (google translator), and thank you for the answers.
leonardo
Re: Not updated inputs after update to 8.0.9
In normal use a raspberry pi user can get temporary root access by prefixing command with "sudo" WinSCP isn't able to prefix command to get root access, You can however log in as "root" if you set up the root user password on pi first.
Thanks for this solution however WinSCP does get root access on my main RaspberryPi (which uses the downloaded Pi + HDD image) by having Shell set to sudo su - in the advanced site settings in WinSCP. Not an issue for me as I'm happy with either solution but there may be security concerns in other environments.
Re: Not updated inputs after update to 8.0.9
@rbreuss; no problem, glad to help
@rjoem; The first 2 questions are to set the root password for the mySQL database root user, it's most important you set this password correctly, The rest are questions about setting up the emoncms database and email. You can accept all the default values except the second emoncms question (4th overall) this password gives emoncms access to mySQL so It should be set to the MySQL root password you just entered for questions 1 & 2. If you make a mistake with the emoncms settings it's not a problem as you can go through the questions again by using sudo dpkg-reconfigure emoncms --force.
@Bra1n; I'm still a novice in the art of WinSCP but I tried the advanced sudo su setting for shell, It only affects the shell commands issued and doesn't affect the browser/filemanager permissions. logged in as pi I'm unable to save edits and if I run ntpd (a sudo only command to correct the UTC time on pi) it tells me it can only be run as root. But if I then set the shells sudo su setting (phew!) the ntpd runs without a hitch but I still cannot save edits. I think the rpi/hdd file/folder permissions may differ to the apt packages maybe. but as long as it works.....
Yes the security is a concern, I believe the sudo method adopted on the pi is intended to eliminate the necessity for a root user to be set up in a bid to tighten security. As it is so easy to enable & disable It's probably best to only enable it as and when required if you are an infrequent user.
Paul
Re: Not updated inputs after update to 8.0.9
I had to go back to v7 and then upgraded via git to v809 but as mentioned by the original poster the rf12piphp will not start now. I have copied the old version rfm12pi back to var/www//emoncms/Modules/raspberrypi and also to init.d and the path is correct in the one in the Node directory. but still it will not load.
When I swap to my v7 emoncms directory which is still on the disk the rfm12pi loads fine so something in the new emoncms directory or subdirectories is stopping it loading but after searching all day I have to admit defeat. Does anyone have any ideas what could be preventing this loading.
Re: Not updated inputs after update to 8.0.9
@ph66: thanks for the help, now it works.
I have another question, my previous system (rasp + HD) had occasionally blocks as described here ( http://openenergymonitor.org/emon/node/3584 ), it is appropraite even in this version upgrade the firmware RFM12 Pi?
Then, the sd card is of 8GB, while the copied image occupies only a part, I can extend using the menu on the raspberry. The HDD is instead an old IDE 20GB, running the command df-h (see image) does not seem to be indicated, to see its use and occupation I have to give another command? using G-parted, which partition can expand to use the whole HDD.
thanks again
leonardo
Re: Not updated inputs after update to 8.0.9
Completely confirmed what ngbod says, I have the same problem. Now I have fully functional system (v 8.0.9) thanks to Paul and his great tutorial above, but it is completely different approach and installation process. When I use standard prebuilt package and upgrade EMONCMS to very latest version via git pull, rf12piphp is not started automaticaly during reboot and is not possible to start it manually (at least Im unable to start it).
Re: Not updated inputs after update to 8.0.9
@ ngbod - reading back some of your earlier posts I can see you're missing the leading / when you edit /etc/init.d/rfm12piphp it should read RPI_BIN="/var/www/emoncms/Modules/raspberrypi/raspberrypi_run.php" try adding the / and then run
sudo update-rc.d rfm12piphp defaults && sudo service rfm12piphp restart
I hope that sorts it as I'm not sure what else it could be. (these previous changes will be reverted on git very shortly, the pull request is currently queued to be merged)
@ rbreuss - the notes above are possibly relevant to your previous installation but not to the apt installed version, if you want to use the previous copy you will have to manually edit parts as ngbod is doing or wait until the changes are reverted on git and try again.
@ rjoem - expanding the partitions is a whole new topic that may be better addressed on a new thread as this one is getting a little busy :-)
Paul
ps by the way rjoem - it's pb66 not ph66
Re: Not updated inputs after update to 8.0.9
Paul, I fully understand, what you say. Im not mixing those two installations.
1) APT way described by you works without problems (there is only one bug regarding My Electricity panel, Trystan already fixed in master, but it remains in my apt installation unfixed yet).
As Im learning various approaches to get more familiar with LINUX, I tried once more that original approach
2) Prebuilt image and upgrade to 8.0.9 via git pull. And this git approach is still unusable, as system stops RFM receiving after upgrade to 8.0.9.
Re: Not updated inputs after update to 8.0.9
@ pb66 ; ok, sorry Paul for the error. But it needs to upgrade the firmware RFM12Pi?
leonardo
Re: Not updated inputs after update to 8.0.9
@ rbreuss - yes, my electric has been fixed but may not have reached a release yet, not every edit on git repo results in a new release, but they are very frequent at the moment so you won't need to wait too long. and regards the git version perhaps wait a while and see if ngbod has any success with the edit, again that will be available on git very soon.
@ rjoem - sorry, missed your earlier Q about rfm2pi firmware, The firmware update is relevant to the rfm2pi board only, regardless of what software you are running if you experience rfm lock-ups/drop-outs it would be a good idea to upgrade firmware.
Paul
Re: Not updated inputs after update to 8.0.9
@ngbod - I think I'm right in saying that the /etc/init.d/rfm12piphp script is the only relevant one (it's not required, or accessed, within the ???/Modules/raspberrypi/ directory, just stored there for convenience in git). However, I'm not sure if this also applies to versions related to the node module.
You can try diffing the rfm12piphp scripts to ensure they really are the same by running
diff /path/to/first/rfm12piphp /path/to/second/rfm12piphp
You should see nothing, but you might see a diff on the config paths between the two files, which would be instructive.
Re: Not updated inputs after update to 8.0.9
Paul, Dave, I checked my typing and all was ok. I diffed the init.d and rapberrypi versions and they are identical. The one in the node directory is different but I think it should be. I replaced the node version with the init.d version but it still didn't work.
When I replace the v8 Modules directory with the v7 one the rfm12pi runs fine. I tried renaming individual modules and replacing them with the v7 ones but it still wouldn't run. I now realise I maybe should have removed the v8 modules not just rename them to find the offending item.
The v8 modules had pi as owner so I changed them all to root like the v7 modules but still it won't run.
Re: Not updated inputs after update to 8.0.9
@rjoem perhaps the post I made in this thread http://openenergymonitor.org/emon/node/3889 may help with your HDD question.
Re: Not updated inputs after update to 8.0.9
I have found this error message when trying to load the rfm12piphp service....
PHP Fatal error: Class 'EmonLogger' not found in /var/www/emoncms/Modules/user/user_model.php on line 34
and also
PHP Fatal error: Class 'EmonLogger' not found in /var/www/emoncms/Modules/input/process_model.php on line 27
The line in both files is the same.....
$this->log = new EmonLogger(__FILE__);
I tried commenting the line out and rfm12piphp then loaded ok but no data was transferred.
Re: Not updated inputs after update to 8.0.9
I've not seen that error message before, but if rfm12piphp is running but not receiving data recheck /boot/cmdline.txt and /etc/inittab again as that is symptom of not enabling serial access for rfm12pi,
Also try restarting rfm12pi with sudo service rfm12piphp restart log and then you can check the log files to see what's happening.
Paul
Re: Not updated inputs after update to 8.0.9
Thanks Paul, I checked the cmdline and inittab and they where correct. The rfm12piphp log doesn't help as it's now complaining about something else.....
Fatal error: Call to a member function info() on a non-object in /var/www/emoncms/Modules/input/process_model.php on line 86
I think I'll just go back to v7 for now as the v8 upgrade is just running me round in circles. I'll wait for a v8 image to hopefully come out.
Re: Not updated inputs after update to 8.0.9
ngbod - the version of process_model in master uses the EmonLogger class - /var/www/emoncms/Modules/log/EmonLogger.php (even if you don't configure emoncms to do any logging, the PHP files still import the logger so you'd need that file if you're mixing and matching versions).
You can see it here (ironically, it's a wrapper so that log4php doesn't cause any issues for people who don't have it installed!)
Re: Not updated inputs after update to 8.0.9
Dave, the file /var/www/emoncms/Modules/log/EmonLogger.php is present but I still get the errors.
I am not mixing and matching git and apt versions. All the installs have been 100% git derived. There has also been no mixing of the v7 and v8 emoncms directories as the v7 directories have been renamed or removed.
I had looked at the log4php statement in the git settings.php file as it points to a non existent file.
// Log4PHP configuration
$log4php_configPath = '/etc/emoncms/emoncms_log4j.xml';
The statement is not present in my apt version of settings.php
Re: Not updated inputs after update to 8.0.9
Just noticed the problematic emonlogger statements are not present in the apt versions of the files either.
Re: Not updated inputs after update to 8.0.9
Are you running 8.0.9 or the head of the master branch? Now that I think about it, it sounds like the latter because the reason logging is not supported in the APT install is because it was merged after 8.0.9...
Could you try running the actual 8.0.9 (I'm guessing you may have more luck?) - you can get this by git checkout 8.0.9 if you're serving up the git repository.
I spent quite a bit of time ensuring the logging would be transparent on legacy installs but perhaps I missed something, so I will check that just now.
Re: Not updated inputs after update to 8.0.9
I ran git checkout master on saturday pm and then installed per the step by step raspberry/ linux instructions on git. After a nice clean install I then saved an image so I could go back to fresh after each attempt to get it to work. It had v8.09 at the bottom of each screen.
Re: Not updated inputs after update to 8.0.9
Guys,
I had fully working system till now, installed from apt by cookbook of Paul, see above in this thread. I just made and upgrade to up-to-date version 8.1.1 by command " sudo apt-get update && sudo apt-get upgrade " recommended by Paul also in above. And result? Communication with RFM12 is again not functional. Does anybody has an idea, what can be wrong this time? Im not LINUX guru, so Im unable to find, where is problem. Is there ANY STABLE version available? I would like to participate in visualisations development, but in case each upgrade makes my system unusable due basic communication malfunction, it is hard.
Radek
Re: Not updated inputs after update to 8.0.9
Radek, it may be that you need to restart the rfm12piphp service with:
sudo service rfm12piphp restart
Re: Not updated inputs after update to 8.0.9
Yes, sure, Trystan, I restarted it man times (either with logging off or on). But it is solved already, I found solution in another thread:
https://github.com/emoncms/raspberrypi/pull/42/files
After I added that missing "require" command, everything works again.
Radek
Re: Not updated inputs after update to 8.0.9
If you use apt to manage your emoncms installation, there's a new version of the raspberrypi module now available which includes the fix from the upstream repo.
You should now be running 1.0.1-1 (which you can confirm by running dpkg -l | grep rfm12pi ) - this should play nicely with all versions of the main emoncms package.
Re: Not updated inputs after update to 8.0.9
I just tried that for laughs as I was running a hand edited rfm12pi version 1.0.1 and after upgrading to 1.0.1-1 got ERROR: file not found : '/var/www/Modules/raspberrypi/raspberrypi_run.php' which is not surprising as the apt install has it at /usr/share/emoncms/www/Modules/raspberrypi/raspberrypi_run.php . Manually editing /etc/init.d/rfm12piphp to point RPI_BIN to the correct location solved the problem.
I've submitted a pull request
Re: Not updated inputs after update to 8.0.9
Good catch. I was thinking about fixing the EmonLogger issue and forgot that the fix to the deployment directory had not previously been a tagged raspberrypi release.
I actually need to write a quilt patch for this so it isn't overwritten by future changes, leaving us back in the same boat - I'll have that up in a couple of hours.
Re: Not updated inputs after update to 8.0.9
That should be fixed with 1.0.1-2 , cheers.


SPLICE’23: CS Education Research Technology
and Data Infrastructure Community Meeting
Eighth SPLICE Workshop Call for Participation
Wednesday, March 15, 2023, Toronto, Canada (An Affiliated Event with SIGCSE’23)
CS educators and CS Ed researchers and developers are invited to the 8th annual SPLICE meeting, focused on creating new Technology and Data Infrastructure for CS Education Research.
The mission of the SPLICE project is to develop Technology and Data Infrastructure for CS Education Research. At this SPLICE community meeting, we invite you to contribute to defining the features of our new SPLICE Portal that will provide this infrastructure.
Who should attend? We encourage you to attend if:
- You have CS learner data (e.g., from a tool or study) and want to analyze or share it.
- You are looking for datasets from CS courses to do analysis (e.g., understand student behavior, train a model).
- You create systems/tools to support CS learning that you want to be useful in other classrooms. Especially if you want your tool to integrate with other tools.
- You teach CS and want to use high-quality learning content and tools (like these examples) made by others.
What will you do at the workshop? You will:
- Learn about existing tools, data and research infrastructure that can help you improve your CS teaching and research, and share your content with others.
- Opportunity to get feedbacvk on your own research or teaching project, with support from like-minded peers, and SPLICE experts who can connect you to datasets, tools, and infrastructure that can help you accomplish your goals.
- Help shape the next generation of CS research infrastructure.
How much does it cost?
- Attendance is free. (However, you are expected to register for SIGCSE’23.) We have some travel funding for the extra night in the hotel that attendance at the workshop will likely require.
To participate in the workshop: Fill out this form: https://forms.gle/GdcTXAkXi29Koqi3A by January 30, 2023.
Communications: We are using a Google Group for email communications: https://groups.google.com/a/vt.edu/g/splice-8th-workshop--sigcse23-toronto-g.
Workshop Agenda
Please see: https://docs.google.com/spreadsheets/d/1MkF0Ci_ryhCWBcnpQnt_7OJ3xIptVNtuFyxqbnqJeAs/edit?usp=sharing
Workshop Hosts
Cliff Shaffer, Virginia Tech
Peter Brusilovsky, University of Pittsburgh
Ken Koedinger, Carnegie Mellon University
Thomas Price, North Carolina State University
Tiffany Barnes, North Carolina State University


My first webpage!
Written with the guidance of Epicodus Online.
This is my first webpage!
Isn't it great?
Here are the things I'm going to learn about:
HTML
CSS
JavaScript


--- title: Quiz Result slug: student-quiz-result-details --- {% extends "layouts/website-account.html" %} {% block pageHeader %}{% endblock %} {% block beforePage %} {% include 'pages/_back-to-course.navbar.html' %}
Submited on 02 Jan 2019


Installation of Joomla on your web server.
Install and Configure Joomla on Your LAMP Server - Debian
Difficulty: 1
Time: 5
Joomla is an open source content management system that helps you build websites and online applications. Joomla is built in PHP and uses a database system such as MySQL.
This article walks you through the installation of Joomla on your Debian server. Before getting started, you need to have LAMP (Linux, Apache, MySQL, PHP) set up on your server. For instructions, see install the LAMP stack
Download Joomla
-
Before you download the installation files, create a directory:
sudo mkdir temp
- Go to that directory:
cd temp
-
Download the latest version of Joomla from the Joomla website:
sudo wget http://joomlacode.org/gf/download/frsrelease/17410/76021/Joomla_2.5.7-Stable-Full_Package.tar.gz
-
Unzip the downloaded package, moving it to the default Apache directory:
sudo tar zxvf Joomla_2.5.7-Stable-Full_Package.tar.gz -C /var/www
-
If the command
tar
is not found, install tar
:
sudo apt-get install tar
Grant permissions
Create Joomla database and user
-
Log into MySQL:
sudo mysql -u root -p
- When prompted, enter the MySQL root password that you set during the MySQL installation.
-
Create a database with any name:
CREATE DATABASE testdb;
The following displays:
Query OK, 1 row affected (0.00 sec)
-
Create a user:
CREATE USER newuser@localhost;
- Set the password for the newly created user:
SET PASSWORD FOR newuser@localhost= PASSWORD("pass");
- Grant privileges to the newly created user:
GRANT ALL PRIVILEGES ON testdb.* TO newuser@localhost IDENTIFIED BY 'pass';
-
Refresh MySQL:
FLUSH PRIVILEGES;
-
Exit the MySQL shell:
exit
-
Restart Apache:
sudo service apache2 restart
Install Joomla
-
In your browser, navigate to
http://server-ip-address/installation
. The Joomla installation page displays.
-
Follow the onscreen instructions for the Pre-installation Check and License.
- Configure the database connection settings, and enter the credentials you created in the previous section.
- Enter configuration information for your website such as the name of the site, email, and password for Admin. Click Install Sample Data.
To complete the installation, you are asked to remove the installation folder.
-
In your console, remove the installation folder, and change the permission on the configuration file.
sudo rm -rf /var/www/installation/
sudo chmod 755 /var/www/configuration.php
- In your browser, navigate to
http://server-ip-address/index.php
or domain name. The new Joomla page displays.
Next steps
Now that you have set up a Joomla site, you can install Joomla Console to manage your Joomla site by command line.


Masjid Baiturrahman
Aceh, Indonesia
About
Baiturrahman Grand Mosque is a Mosque located in the center of Banda Aceh city, Aceh Province, Indonesia . The Baiturrahman Grand Mosque is a symbol of religion, culture, spirit, strength, struggle and nationalism of the Acehnese people.
The mosque is a landmark of Banda Aceh and has survived the 2004 Indian Ocean tsunami.
Featured Event
Takbiran
Language
Bahasa Indonesia
Foods
Mie Aceh, Kopi Aceh
Members are going
Trip Information
| Date of departure | 22 Aug, 2020 |
|---|---|
| Duration | 4D 3N |
| Type | Open Trip |
| Price | $80,00/person |


Former Super Junior member Hangeng rumored to be marrying Hong Kong actress Celina Jade
by germainejFormer Super Junior member Hangeng is rumored to be marrying Hong Kong actress Celina Jade.
On November 8, Chinese media outlet Sina reported Hangeng and Celina Jade have started sending out wedding invitations to friends and family. The two celebrities reportedly registered their marriage in June of last year, and at the time, both their labels responded, "Thank you for the interest. We'll let you know if there's good news."
According to Sina, both Hangeng and Celina Jade's labels are not answering questions about their rumored wedding. The couple went public with their relationship in February of 2018 after meeting in 2017 at at award ceremony.
Stay tuned for updates.