Re: Class, constructor and inherance.
On 16/10/15 4:14 PM, holo wrote: I created interface IfRequestHandler it is used only by one class RequestHandlerXML right now but thanks to such solution i can create more classes with same interface which can handle it in different way.. eg second can be RequestHandlerCSVReport or RequestHandlerSendViaEmail. Is it this what you ware mentioning? Bellow working code: / //main.d: / #!/usr/bin/rdmd import std.stdio, sigv4, conf; void main() { ResultHandlerXML hand = new ResultHandlerXML; SigV4 req = new SigV4(hand); //req.ResultHandler = hand; req.go(); hand.processResult(); } / //conf.d: / module conf; import std.stdio, std.process; import std.net.curl:exit; interface IfConfig { void set(string val, string var); string get(string var); } class Config : IfConfig { this() { this.accKey = environment.get("AWS_ACCESS_KEY"); if(accKey is null) { writeln("accessKey not available"); exit(-1); } this.secKey = environment.get("AWS_SECRET_KEY"); if(secKey is null) { writeln("secretKey not available"); exit(-1); } } public: void set(string val, string var) { switch(var) { case "accKey": accKey = val; break; case "secKey": secKey = val; break; default: writeln("Can not be set, not such value"); } } string get(string var) { string str = ""; switch(var) { case "accKey": return accKey; case "secKey": return secKey; default: writeln("Can not be get, not such value"); } return str; } // private: string accKey; string secKey; } / //sigv4.d / module sigv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; import conf; interface IfSigV4 { IfResultHandler go(ResultHandlerXML ResultHandler); } interface IfResultHandler { void setResult(int content); void processResult(); } class ResultHandlerXML : IfResultHandler { void setResult(int content) { this.xmlresult = content; } void processResult() { writeln(xmlresult); } private: int xmlresult; } class SigV4 : IfSigV4 { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances") in { writeln(parmStr); } body { conf.Config config = new conf.Config; this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.requestParameters = parmStr; this.accessKey = config.get("accKey"); if(accessKey is null) { writeln("accessKey not available"); exit(-1); } this.secretKey = config.get("secKey"); if(secretKey is null) { writeln("secretKey not available"); exit(-1); } } public: string method; string service; string host; string region; string endpoint; string payload; string requestParameters; IfResultHandler ResultHandler; IfResultHandler go(ResultHandlerXML ResultHandler) { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = requestParameters ~ this.Version; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryString, canonicalHeadersString, signedHeaders); string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request"; string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ creden
Re: Class, constructor and inherance.
I created interface IfRequestHandler it is used only by one class RequestHandlerXML right now but thanks to such solution i can create more classes with same interface which can handle it in different way.. eg second can be RequestHandlerCSVReport or RequestHandlerSendViaEmail. Is it this what you ware mentioning? Bellow working code: / //main.d: / #!/usr/bin/rdmd import std.stdio, sigv4, conf; void main() { ResultHandlerXML hand = new ResultHandlerXML; SigV4 req = new SigV4(hand); //req.ResultHandler = hand; req.go(); hand.processResult(); } / //conf.d: / module conf; import std.stdio, std.process; import std.net.curl:exit; interface IfConfig { void set(string val, string var); string get(string var); } class Config : IfConfig { this() { this.accKey = environment.get("AWS_ACCESS_KEY"); if(accKey is null) { writeln("accessKey not available"); exit(-1); } this.secKey = environment.get("AWS_SECRET_KEY"); if(secKey is null) { writeln("secretKey not available"); exit(-1); } } public: void set(string val, string var) { switch(var) { case "accKey": accKey = val; break; case "secKey": secKey = val; break; default: writeln("Can not be set, not such value"); } } string get(string var) { string str = ""; switch(var) { case "accKey": return accKey; case "secKey": return secKey; default: writeln("Can not be get, not such value"); } return str; } // private: string accKey; string secKey; } / //sigv4.d / module sigv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; import conf; interface IfSigV4 { IfResultHandler go(ResultHandlerXML ResultHandler); } interface IfResultHandler { void setResult(int content); void processResult(); } class ResultHandlerXML : IfResultHandler { void setResult(int content) { this.xmlresult = content; } void processResult() { writeln(xmlresult); } private: int xmlresult; } class SigV4 : IfSigV4 { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances") in { writeln(parmStr); } body { conf.Config config = new conf.Config; this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.requestParameters = parmStr; this.accessKey = config.get("accKey"); if(accessKey is null) { writeln("accessKey not available"); exit(-1); } this.secretKey = config.get("secKey"); if(secretKey is null) { writeln("secretKey not available"); exit(-1); } } public: string method; string service; string host; string region; string endpoint; string payload; string requestParameters; IfResultHandler ResultHandler; IfResultHandler go(ResultHandlerXML ResultHandler) { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = requestParameters ~ this.Version; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryStri
Re: Class, constructor and inherance.
Thank you for example. I asked about it programmers at work too - PHP guys - and they explained me how you are see usage of that interfaces in my code. They prepare for me some "skeleton" on which i will try to build my solution. Will be back if i will have some code.
Re: Class, constructor and inherance.
On 15/10/15 5:43 PM, holo wrote: Please again, any example? I'm trying to figure out how it should be done but i don't have any base from which i can build some solution. #!/usr/bin/rdmd import std.stdio; interface RequestResult { int add (int x); } class B : RequestResult { int add(int x) { return ++x; } } class A { RequestResult go(int varA, int varB) { return add(varA + varB); } } void main() { B b = new B(); A a = new A(); int x = 12; int y = 15; RequestResult c = A.go(x, y); } It even don't want to compile, but that probably not what you ware thinking about. [holo@ultraxps workplace]$ dmd test.d test.d(24): Error: undefined identifier 'add' test.d(38): Error: need 'this' for 'go' of type 'RequestResult(int varA, int varB)' [holo@ultraxps workplace]$ interface IA { IB do(int x, int y); } interface IB { int z(); } class A : IA { IB do(int x, int y) {return new B(x + y);} } class B : IB { private int value; this(int value) { this.value = value; } int z() { return value; } void proof() { import std.stdio; writeln("proof this is B"); } } void main() { IA a = new A(); IB b = a.do(1, 1); B realB = cast(B)b; realB.proof(); } b.proof() won't compile obviously, since IB does not have a proof method. The point here is to separate out the object gained from how you go it. So that the implementation on how to get it doesn't matter. That way it can be swapped at runtime without any ill effects.
Re: Class, constructor and inherance.
Please again, any example? I'm trying to figure out how it should be done but i don't have any base from which i can build some solution. #!/usr/bin/rdmd import std.stdio; interface RequestResult { int add (int x); } class B : RequestResult { int add(int x) { return ++x; } } class A { RequestResult go(int varA, int varB) { return add(varA + varB); } } void main() { B b = new B(); A a = new A(); int x = 12; int y = 15; RequestResult c = A.go(x, y); } It even don't want to compile, but that probably not what you ware thinking about. [holo@ultraxps workplace]$ dmd test.d test.d(24): Error: undefined identifier 'add' test.d(38): Error: need 'this' for 'go' of type 'RequestResult(int varA, int varB)' [holo@ultraxps workplace]$
Re: Class, constructor and inherance.
On 15/10/15 4:45 PM, holo wrote: Just some ideas: interface RequestResult { ... } RequestResult go(string[string] requestParameters) Basically it is same what you wrote in one of first posts. Interface is for declaration of methods which need to be implemented in class. How in that case is it possible to return RequestResult which is basically xml form as function/s and one of it will be go itself? Do you have any link to such solution which i can take as example? I was looking for it but didn't find such solution. One idea interface RequestResult { string doSomethingWithXML(string xmlString); RequestResult go(); //or just not put here that go? } Class SigV4 : RequestResult { ... go() { string xml; ... return doSomethingWithXML(xml); } doSomethingWithXML(string xmlString) { ... } } but i still don't see how it could work like that. SigV4 would not inherit from RequestResult. Credential interface provides a method to make the requests. RequestResult would be just an abstraction around what you expect to get back. The abstraction allows so that interface is what you will commonly need. You can cast to the specific implementation e.g. SigV4Result to get access to resulting data from the SigV4 process.
Re: Class, constructor and inherance.
Just some ideas: interface RequestResult { ... } RequestResult go(string[string] requestParameters) Basically it is same what you wrote in one of first posts. Interface is for declaration of methods which need to be implemented in class. How in that case is it possible to return RequestResult which is basically xml form as function/s and one of it will be go itself? Do you have any link to such solution which i can take as example? I was looking for it but didn't find such solution. One idea interface RequestResult { string doSomethingWithXML(string xmlString); RequestResult go(); //or just not put here that go? } Class SigV4 : RequestResult { ... go() { string xml; ... return doSomethingWithXML(xml); } doSomethingWithXML(string xmlString) { ... } } but i still don't see how it could work like that.
Re: Class, constructor and inherance.
On 15/10/15 8:15 AM, holo wrote: I want to ask you for advises what i could do with that class to make it looks more "pro"/elegant/build in "proper way". Probably there are lot of mistakes which all beginners are doing. eg.: Did i use interface correctly? You are reasonably close: credential sig = new sigv4(); Why are you creating sigv4 object with type credential? How in your opinion should look interface for such class? Although go is not really doing what I expect it to do. To me go should be dedicated to performing a request given what ever you need for just that request. The class sigv4 is your global state aka what doesn't change per request. To me what go returns is whatever is the common denominator for what you need from it is. Not sure if i correctly understood that. Do you propose to take out eg signing process from go function and let it only to make requests? Signature is depending on kind of request and accurate time when request is send. That is why i all that things put to it. The implementation such as sigv4 can be configured with as much detail as possible extra that you need. The method go can for instance do what ever it needs to, to for fill it's goal. From what I can see, you probably want go to take the payload as an argument. That way you can reuse an instance of sigv4. Which is the ultimate goal. In plan i wanted to change variables per request that why i left that public variables and created that arguments for constructor - to have possibility to change that values durring creation of object. On example, im expecting it will be behaving like that: sigv4 obj = new sigv4(); content = obj.go();//will get instances list obj.request_parameters = "Action=DescribeRegions&Version=2013-10-15" content2 = obj.go();//will get list of regions destroy(obj); so that go will get me back what i need per request not per one object live, or it wont work like that? It indeed should not. Also remember go is currently returning an integer. Not data from the request. I test it with such code: void main() { SigV4 sig = new SigV4(); writeln(sig.go); sig.requestParameters = "Action=DescribeRegions&Version=2013-10-15"; writeln(sig.go()); } Actually it is working, first it returned to me default request DescribeInstances and right after that request DescirbeRegions. I understand that, before i will start parsing it with xml lib i need to convert it to string. Should it be solved in other way? go method returns xml form (need to find out how force AWS to return JSON cos i saw xml module in dlang is deprecated) with structures depends on query - in default query that will be list of instances with all parameters. That xml file i want to parse in higher classes/functions (different class for different request). If you need to use std.xml use it. We don't appear to be replacing it any time soon. So here is the thing. You are tieing your usage of the API to SigV4 standard. This is bad bad bad. Any updates or changes to it, will cause problems. If you want to tie yourself to said standard, then you don't need OOP. How it could be solved in that case to not be tied to SigV4? If there will came some other request signing process it will need to be implement in that "go" function. Is there possibility to make it universal for all kind of signing processes? How it should be done in OOP (some example, pseudo code)? Or i missed what you are pointing to? Another thing, you may want to consider to use an interface as the return type of go. That way your implementation of it can have extra fields/methods which if you know that it is sigv4 you can cast to, to get access to, should you need it. It interesting what you wrote. Can you show me some example (pseudo code) how it can be implemented and how it could be used? It think that it is what you wrote in previous post: Credential sigv4 = new sigv4(); Remember im really beginner and some obvious things are not necessarily such for me. :) Also classes start with a capital letter, like Credential or SigV4. And D prefers camal casing aka requestParameters for variables/functions. Updated my code according to those directions. //holo Just some ideas: interface RequestResult { ... } RequestResult go(string[string] requestParameters)
Re: Class, constructor and inherance.
I want to ask you for advises what i could do with that class to make it looks more "pro"/elegant/build in "proper way". Probably there are lot of mistakes which all beginners are doing. eg.: Did i use interface correctly? You are reasonably close: credential sig = new sigv4(); Why are you creating sigv4 object with type credential? How in your opinion should look interface for such class? Although go is not really doing what I expect it to do. To me go should be dedicated to performing a request given what ever you need for just that request. The class sigv4 is your global state aka what doesn't change per request. To me what go returns is whatever is the common denominator for what you need from it is. Not sure if i correctly understood that. Do you propose to take out eg signing process from go function and let it only to make requests? Signature is depending on kind of request and accurate time when request is send. That is why i all that things put to it. The implementation such as sigv4 can be configured with as much detail as possible extra that you need. The method go can for instance do what ever it needs to, to for fill it's goal. From what I can see, you probably want go to take the payload as an argument. That way you can reuse an instance of sigv4. Which is the ultimate goal. In plan i wanted to change variables per request that why i left that public variables and created that arguments for constructor - to have possibility to change that values durring creation of object. On example, im expecting it will be behaving like that: sigv4 obj = new sigv4(); content = obj.go();//will get instances list obj.request_parameters = "Action=DescribeRegions&Version=2013-10-15" content2 = obj.go();//will get list of regions destroy(obj); so that go will get me back what i need per request not per one object live, or it wont work like that? It indeed should not. Also remember go is currently returning an integer. Not data from the request. I test it with such code: void main() { SigV4 sig = new SigV4(); writeln(sig.go); sig.requestParameters = "Action=DescribeRegions&Version=2013-10-15"; writeln(sig.go()); } Actually it is working, first it returned to me default request DescribeInstances and right after that request DescirbeRegions. I understand that, before i will start parsing it with xml lib i need to convert it to string. Should it be solved in other way? go method returns xml form (need to find out how force AWS to return JSON cos i saw xml module in dlang is deprecated) with structures depends on query - in default query that will be list of instances with all parameters. That xml file i want to parse in higher classes/functions (different class for different request). If you need to use std.xml use it. We don't appear to be replacing it any time soon. So here is the thing. You are tieing your usage of the API to SigV4 standard. This is bad bad bad. Any updates or changes to it, will cause problems. If you want to tie yourself to said standard, then you don't need OOP. How it could be solved in that case to not be tied to SigV4? If there will came some other request signing process it will need to be implement in that "go" function. Is there possibility to make it universal for all kind of signing processes? How it should be done in OOP (some example, pseudo code)? Or i missed what you are pointing to? Another thing, you may want to consider to use an interface as the return type of go. That way your implementation of it can have extra fields/methods which if you know that it is sigv4 you can cast to, to get access to, should you need it. It interesting what you wrote. Can you show me some example (pseudo code) how it can be implemented and how it could be used? It think that it is what you wrote in previous post: Credential sigv4 = new sigv4(); Remember im really beginner and some obvious things are not necessarily such for me. :) Also classes start with a capital letter, like Credential or SigV4. And D prefers camal casing aka requestParameters for variables/functions. Updated my code according to those directions. //holo
Re: Class, constructor and inherance.
On 13/10/15 5:17 PM, holo wrote: On Tuesday, 13 October 2015 at 02:03:46 UTC, Rikki Cattermole wrote: On 13/10/15 5:56 AM, holo wrote: @Rikki: If you didn't need to make it easily changeable I would say not even bother with OOP at all. Basically that what i had was enough for me and on top of that i could build my app. It need to just periodically check for new instances and if they are started or stopped and count "up and running time" for billing purpose. But like i said i want to learn programming in D and basically OOP too so i want to make it "proper way". BTW: i think right now i understand what tuple is, but still don't know for what to duplicate struct functionalities :). Those Templates still don't understand but i hope that will came naturally with time and practice. eg.. they are very similar to normal functions but you can call it with types not only attributes.. strange ;) I red yours advises and try to create according to it my own first class. I moved time functions and variables to method "go" they need to be current as possible when im sending request, if wont authorization could not pass.. so i think they shouldn't be in constructor. I moved some other variables too, and created interface. From all that things came out such monster which is working and doing its job :) module sigawsv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; interface credential { int go(); } class sigv4 : credential { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances&Version=2013-10-15") { this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.request_parameters = parmStr; this.accessKey = environment.get("AWS_ACCESS_KEY"); this.secretKey = environment.get("AWS_SECRET_KEY"); } public: string method; string service; string host; string region; string endpoint; string payload; string request_parameters; int go() { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = request_parameters; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryString, canonicalHeadersString, signedHeaders); string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request"; string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ credentialScope ~ "\n" ~ sha256Of(canonicalRequest).toHexString.toLower; auto signingKey = getSignatureKey(secretKey, curDateStr, region, service); string signature = hmac!SHA256(stringToSign.representation, signingKey).toHexString.toLower; string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ signedHeaders ~ ", " ~ "Signature=" ~ signature; auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString); client.method = HTTP.Method.get; client.addRequestHeader("x-amz-date", xamztime); client.addRequestHeader("Authorization", authorizationHeader); auto content = client.perform(); return content; } private: const algorithm = "AWS4-HMAC-SHA256"; string accessKey; string secretKey; string currentClock; string currentDate; string curDateStr; string currentTime; string curTimeStr; string xamztime; string canonicalURI; string canonicalQueryString; string canonicalHeadersString; string signedHeaders; alias sign = hmac!SHA256; auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { auto kString = ("AWS4" ~ key).representation; auto kDate
Re: Class, constructor and inherance.
On Tuesday, 13 October 2015 at 02:03:46 UTC, Rikki Cattermole wrote: On 13/10/15 5:56 AM, holo wrote: @Rikki: If you didn't need to make it easily changeable I would say not even bother with OOP at all. Basically that what i had was enough for me and on top of that i could build my app. It need to just periodically check for new instances and if they are started or stopped and count "up and running time" for billing purpose. But like i said i want to learn programming in D and basically OOP too so i want to make it "proper way". BTW: i think right now i understand what tuple is, but still don't know for what to duplicate struct functionalities :). Those Templates still don't understand but i hope that will came naturally with time and practice. eg.. they are very similar to normal functions but you can call it with types not only attributes.. strange ;) I red yours advises and try to create according to it my own first class. I moved time functions and variables to method "go" they need to be current as possible when im sending request, if wont authorization could not pass.. so i think they shouldn't be in constructor. I moved some other variables too, and created interface. From all that things came out such monster which is working and doing its job :) module sigawsv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; interface credential { int go(); } class sigv4 : credential { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances&Version=2013-10-15") { this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.request_parameters = parmStr; this.accessKey = environment.get("AWS_ACCESS_KEY"); this.secretKey = environment.get("AWS_SECRET_KEY"); } public: string method; string service; string host; string region; string endpoint; string payload; string request_parameters; int go() { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = request_parameters; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryString, canonicalHeadersString, signedHeaders); string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request"; string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ credentialScope ~ "\n" ~ sha256Of(canonicalRequest).toHexString.toLower; auto signingKey = getSignatureKey(secretKey, curDateStr, region, service); string signature = hmac!SHA256(stringToSign.representation, signingKey).toHexString.toLower; string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ signedHeaders ~ ", " ~ "Signature=" ~ signature; auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString); client.method = HTTP.Method.get; client.addRequestHeader("x-amz-date", xamztime); client.addRequestHeader("Authorization", authorizationHeader); auto content = client.perform(); return content; } private: const algorithm = "AWS4-HMAC-SHA256"; string accessKey; string secretKey; string currentClock; string currentDate; string curDateStr; string currentTime; string curTimeStr; string xamztime; string canonicalURI; string canonicalQueryString; string canonicalHeadersString; string signedHeaders; alias sign = hmac!SHA256; auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { auto kString = ("AWS4" ~ key).representation;
Re: Class, constructor and inherance.
On 13/10/15 5:56 AM, holo wrote: @Rikki: If you didn't need to make it easily changeable I would say not even bother with OOP at all. Basically that what i had was enough for me and on top of that i could build my app. It need to just periodically check for new instances and if they are started or stopped and count "up and running time" for billing purpose. But like i said i want to learn programming in D and basically OOP too so i want to make it "proper way". BTW: i think right now i understand what tuple is, but still don't know for what to duplicate struct functionalities :). Those Templates still don't understand but i hope that will came naturally with time and practice. eg.. they are very similar to normal functions but you can call it with types not only attributes.. strange ;) I red yours advises and try to create according to it my own first class. I moved time functions and variables to method "go" they need to be current as possible when im sending request, if wont authorization could not pass.. so i think they shouldn't be in constructor. I moved some other variables too, and created interface. From all that things came out such monster which is working and doing its job :) module sigawsv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; interface credential { int go(); } class sigv4 : credential { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances&Version=2013-10-15") { this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.request_parameters = parmStr; this.accessKey = environment.get("AWS_ACCESS_KEY"); this.secretKey = environment.get("AWS_SECRET_KEY"); } public: string method; string service; string host; string region; string endpoint; string payload; string request_parameters; int go() { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = request_parameters; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryString, canonicalHeadersString, signedHeaders); string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request"; string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ credentialScope ~ "\n" ~ sha256Of(canonicalRequest).toHexString.toLower; auto signingKey = getSignatureKey(secretKey, curDateStr, region, service); string signature = hmac!SHA256(stringToSign.representation, signingKey).toHexString.toLower; string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ signedHeaders ~ ", " ~ "Signature=" ~ signature; auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString); client.method = HTTP.Method.get; client.addRequestHeader("x-amz-date", xamztime); client.addRequestHeader("Authorization", authorizationHeader); auto content = client.perform(); return content; } private: const algorithm = "AWS4-HMAC-SHA256"; string accessKey; string secretKey; string currentClock; string currentDate; string curDateStr; string currentTime; string curTimeStr; string xamztime; string canonicalURI; string canonicalQueryString; string canonicalHeadersString; string signedHeaders; alias sign = hmac!SHA256; auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { auto kString = ("AWS4" ~ key).representation; auto kDate = sign(dateStamp.representation, kString); auto kRegion = sign(regionName.representation, k
Re: Class, constructor and inherance.
@Rikki: If you didn't need to make it easily changeable I would say not even bother with OOP at all. Basically that what i had was enough for me and on top of that i could build my app. It need to just periodically check for new instances and if they are started or stopped and count "up and running time" for billing purpose. But like i said i want to learn programming in D and basically OOP too so i want to make it "proper way". BTW: i think right now i understand what tuple is, but still don't know for what to duplicate struct functionalities :). Those Templates still don't understand but i hope that will came naturally with time and practice. eg.. they are very similar to normal functions but you can call it with types not only attributes.. strange ;) I red yours advises and try to create according to it my own first class. I moved time functions and variables to method "go" they need to be current as possible when im sending request, if wont authorization could not pass.. so i think they shouldn't be in constructor. I moved some other variables too, and created interface. From all that things came out such monster which is working and doing its job :) module sigawsv4; import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; interface credential { int go(); } class sigv4 : credential { //could be changed to take some structure as parameter instead of such ammount of attributes this(string methodStr = "GET", string serviceStr = "ec2", string hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", string endpointStr = "https://ec2.amazonaws.com";, string payloadStr = "", string parmStr = "Action=DescribeInstances&Version=2013-10-15") { this.method = methodStr; this.service = serviceStr; this.host = hostStr; this.region = regionStr; this.endpoint = endpointStr; this.payload = payloadStr; this.request_parameters = parmStr; this.accessKey = environment.get("AWS_ACCESS_KEY"); this.secretKey = environment.get("AWS_SECRET_KEY"); } public: string method; string service; string host; string region; string endpoint; string payload; string request_parameters; int go() { //time need to be set when we are sending request not before auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; canonicalURI = "/"; canonicalQueryString = request_parameters; canonicalHeadersString = "host:" ~ this.host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n"; signedHeaders = "host;x-amz-date"; auto canonicalRequest = getCanonicalRequest(canonicalURI, canonicalQueryString, canonicalHeadersString, signedHeaders); string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ service ~ "/" ~ "aws4_request"; string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ credentialScope ~ "\n" ~ sha256Of(canonicalRequest).toHexString.toLower; auto signingKey = getSignatureKey(secretKey, curDateStr, region, service); string signature = hmac!SHA256(stringToSign.representation, signingKey).toHexString.toLower; string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ signedHeaders ~ ", " ~ "Signature=" ~ signature; auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString); client.method = HTTP.Method.get; client.addRequestHeader("x-amz-date", xamztime); client.addRequestHeader("Authorization", authorizationHeader); auto content = client.perform(); return content; } private: const algorithm = "AWS4-HMAC-SHA256"; string accessKey; string secretKey; string currentClock; string currentDate; string curDateStr; string currentTime; string curTimeStr; string xamztime; string canonicalURI; string canonicalQueryString; string canonicalHeaders
Re: Class, constructor and inherance.
On 10/11/2015 10:35 PM, anonymous wrote: On Monday 12 October 2015 07:28, Ali Çehreli wrote: For example, you cannot get current time at run time. I think you mean compile time here. Thanks. :) Ali
Re: Class, constructor and inherance.
On Monday 12 October 2015 07:28, Ali Çehreli wrote: > For example, you cannot get current time at run time. I think you mean compile time here.
Re: Class, constructor and inherance.
On 10/11/2015 08:26 PM, holo wrote: > On Monday, 12 October 2015 at 02:30:43 UTC, Meta wrote: >> On Monday, 12 October 2015 at 02:14:35 UTC, holo wrote: >>> class credential >>> { >>> auto accessKey = environment.get["AWS_ACCESS_KEY"]; >>> auto secretKey = environment.get["AWS_SECRET_KEY"]; >>> } >>> >>> class sigv4 : credential >>> { >>> private: >>> const algorithm = "AWS4-HMAC-SHA256"; >>> >>> auto currentClock = Clock.currTime(UTC()); >>> auto currentDate = cast(Date)currentClock; >>> auto curDateStr = currentDate.toISOString; >>> auto currentTime = cast(TimeOfDay)currentClock; >>> auto curTimeStr = currentTime.toISOString; >>> auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; >>> } >> >> You should set these in the constructor rather than in the class body >> (the only one that's okay to intialize here is `algorithm`, as it's a >> const string). > > I rewrite it to something like this: What Meta is saying is that the expressions used for default values class bodies must be known at compile time. For example, you cannot get current time at run time. Besides, if it did work, there is the question of "should every sigv4 object get the same default value currentClock, or should every object get their own time?" > class credential > { > auto accessKey = environment.get["AWS_ACCESS_KEY"]; > auto secretKey = environment.get["AWS_SECRET_KEY"]; > } As mentioned, that cannot compile. > class sigv4 : credential > { > this(string URI = "/", string queryStr = > "Action=DescribeInstances&Version=2013-10-15", string headerStr = > "host:" ~ host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n", string headers > = "host;x-amz-date") > { > auto currentClock = Clock.currTime(UTC()); That is a known error, which is usually caused by copy-paste: Because you used 'auot' on the left-hand side, that is the definition of a local variable. 'currentClock' above is not the member of this class. It is adviced to use fully qualify members with this. in constructors: this.currentClock = // ... > auto currentClock = Clock.currTime(UTC()); Just define the members without a default value; they will be initialized in the constructor: SysTime currentDate; > My question was too if now i will inherit that class, will that default > values be in child class available? Yes, every variable will obey its default value. When in doubt, test with simple examples. :) class Base { int i = 42; } class Derived : Base { int j; this() { this.j = 100; } } void main() { auto d = new Derived(); assert(d.i == 42); // set by default value assert(d.j == 100);// set in the constructor } Ali
Re: Class, constructor and inherance.
On Monday, 12 October 2015 at 03:29:12 UTC, Rikki Cattermole wrote: On 12/10/15 4:13 PM, holo wrote: By the looks, I'm guessing you do not have much experience when it comes to OOP. I think you are wanting something a bit closer to: import std.typecons : tuple, TypeTuple; interface Credential { string encode(); } class SigV4 : Credential { this() { } string encode() { } private: } TypeTuple!(string, string) AWSKeys() { import std.process; return tuple(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); } Yes you guessed good, i don't have any experience with OOP (i have some experience with C - simple AVR projects and tons of bash scripts) this is my first such kind of language which I'm trying to learn. For beginning I'm trying to avoid advanced things like templates or from your example touples (Touples looks for me like some kind of array but every cell can be different type, am i right? Eg tuple from your example is that same what string[2] var?) i was reading about it but for now i can't understand what they are and for what they are useful. Templates are just compile time arguments :) Mostly used for types and constants. Simple concept, just don't get too scared off by what is possible with template if's. Tuples are pretty simple. It's basically just a struct. They are not arrays. But they do have a similar behavior. With opIndex overloading. You could for example use: struct AWSKeys { string access, secret; static AWSKeys get() { import std.process : environment; return AWSKeys(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); } } Instead of that free function and tuples. I'm trying to learn on the examples and honestly i'm not understand how that TypeTuple is resolving my problem with default values for classes? It wasn't meant to, I got started rewriting the example code you gave, and ehh gave up after the basics of the class/interface. Second thing that interfaces, are they needed? Without it you can write same function just compilator wont be screaming for it lack. An interface basically says, this object adheres to these methods. When dealing with possibly changing authentication/communication protocols you would have the interface being how you get what to send, but the actual implementation being whatever you want to be using. Keep in mind, this class which handles creating the messages to the remote api's is not per message sent. It is a global communication mechanism. If you didn't need to make it easily changeable I would say not even bother with OOP at all. I would recommend coming on to #d on Freenode, we can help you better there. Thank you for explanation tomorrow (today) will back to it and read it carefully, will join IRC too. //almost 6:00AM here :)
Re: Class, constructor and inherance.
On 12/10/15 4:13 PM, holo wrote: By the looks, I'm guessing you do not have much experience when it comes to OOP. I think you are wanting something a bit closer to: import std.typecons : tuple, TypeTuple; interface Credential { string encode(); } class SigV4 : Credential { this() { } string encode() { } private: } TypeTuple!(string, string) AWSKeys() { import std.process; return tuple(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); } Yes you guessed good, i don't have any experience with OOP (i have some experience with C - simple AVR projects and tons of bash scripts) this is my first such kind of language which I'm trying to learn. For beginning I'm trying to avoid advanced things like templates or from your example touples (Touples looks for me like some kind of array but every cell can be different type, am i right? Eg tuple from your example is that same what string[2] var?) i was reading about it but for now i can't understand what they are and for what they are useful. Templates are just compile time arguments :) Mostly used for types and constants. Simple concept, just don't get too scared off by what is possible with template if's. Tuples are pretty simple. It's basically just a struct. They are not arrays. But they do have a similar behavior. With opIndex overloading. You could for example use: struct AWSKeys { string access, secret; static AWSKeys get() { import std.process : environment; return AWSKeys(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); } } Instead of that free function and tuples. I'm trying to learn on the examples and honestly i'm not understand how that TypeTuple is resolving my problem with default values for classes? It wasn't meant to, I got started rewriting the example code you gave, and ehh gave up after the basics of the class/interface. Second thing that interfaces, are they needed? Without it you can write same function just compilator wont be screaming for it lack. An interface basically says, this object adheres to these methods. When dealing with possibly changing authentication/communication protocols you would have the interface being how you get what to send, but the actual implementation being whatever you want to be using. Keep in mind, this class which handles creating the messages to the remote api's is not per message sent. It is a global communication mechanism. If you didn't need to make it easily changeable I would say not even bother with OOP at all. I would recommend coming on to #d on Freenode, we can help you better there.
Re: Class, constructor and inherance.
On Monday, 12 October 2015 at 02:30:43 UTC, Meta wrote: On Monday, 12 October 2015 at 02:14:35 UTC, holo wrote: class credential { auto accessKey = environment.get["AWS_ACCESS_KEY"]; auto secretKey = environment.get["AWS_SECRET_KEY"]; } class sigv4 : credential { private: const algorithm = "AWS4-HMAC-SHA256"; auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; } You should set these in the constructor rather than in the class body (the only one that's okay to intialize here is `algorithm`, as it's a const string). I rewrite it to something like this: module sigawsv4 import std.stdio, std.process; import std.digest.sha, std.digest.hmac; import std.string; import std.conv; import std.datetime; import std.net.curl; class credential { auto accessKey = environment.get["AWS_ACCESS_KEY"]; auto secretKey = environment.get["AWS_SECRET_KEY"]; } class sigv4 : credential { this(string URI = "/", string queryStr = "Action=DescribeInstances&Version=2013-10-15", string headerStr = "host:" ~ host ~ "\n" ~ "x-amz-date:" ~ xamztime ~ "\n", string headers = "host;x-amz-date") { auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; string canonicalURI = URI; string canonicalQueryString = queryStr; string canonicalHeaderString = headerStr; string signedHeaders = headers; } public: string method; string service; string host; string region; string endpoint; string request_parameters; string payload; private: const algorithm = "AWS4-HMAC-SHA256"; auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; auto hmac_sha256(ubyte[] key, ubyte[] msg) { auto hmac = hmac!SHA256(key); hmac.put(msg); auto digest = hmac.finish; return digest; } auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { ubyte[] kString = cast(ubyte[])("AWS4" ~ key); auto kDate = sign(kString, cast(ubyte[])dateStamp); auto kRegion = sign(kDate, cast(ubyte[])regionName); auto kService = sign(kRegion, cast(ubyte[])serviceName); auto kSigning = sign(kService, cast(ubyte[])"aws4_request"); return kSigning; } auto getCanonicalRequest(string canonicalURI, string canonicalQueryString, string canonicalHeaderString, string signedHeaders) { string payloadHash = sha256Of("").toHexString.toLower; string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ signedHeaders ~ "\n" ~ payloadHash; } } Is right now that constructor ok? My question was too if now i will inherit that class, will that default values be in child class available?
Re: Class, constructor and inherance.
By the looks, I'm guessing you do not have much experience when it comes to OOP. I think you are wanting something a bit closer to: import std.typecons : tuple, TypeTuple; interface Credential { string encode(); } class SigV4 : Credential { this() { } string encode() { } private: } TypeTuple!(string, string) AWSKeys() { import std.process; return tuple(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); } Yes you guessed good, i don't have any experience with OOP (i have some experience with C - simple AVR projects and tons of bash scripts) this is my first such kind of language which I'm trying to learn. For beginning I'm trying to avoid advanced things like templates or from your example touples (Touples looks for me like some kind of array but every cell can be different type, am i right? Eg tuple from your example is that same what string[2] var?) i was reading about it but for now i can't understand what they are and for what they are useful. I'm trying to learn on the examples and honestly i'm not understand how that TypeTuple is resolving my problem with default values for classes? Second thing that interfaces, are they needed? Without it you can write same function just compilator wont be screaming for it lack.
Re: Class, constructor and inherance.
On Monday, 12 October 2015 at 02:14:35 UTC, holo wrote: class credential { auto accessKey = environment.get["AWS_ACCESS_KEY"]; auto secretKey = environment.get["AWS_SECRET_KEY"]; } class sigv4 : credential { private: const algorithm = "AWS4-HMAC-SHA256"; auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; } You should set these in the constructor rather than in the class body (the only one that's okay to intialize here is `algorithm`, as it's a const string).
Re: Class, constructor and inherance.
On 12/10/15 3:14 PM, holo wrote: Hello I'm trying to write my first class. I want to use it as module and build anothers on top of it. I read that default functions attributes are not inherited. Is it that same for constructor? This is how my class (not finished) is looking right now: class credential { auto accessKey = environment.get["AWS_ACCESS_KEY"]; auto secretKey = environment.get["AWS_SECRET_KEY"]; } class sigv4 : credential { public: string method; string service; string host; string region; string endpoint; string request_parameters; string payload; private: const algorithm = "AWS4-HMAC-SHA256"; auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; auto hmac_sha256(ubyte[] key, ubyte[] msg) { auto hmac = hmac!SHA256(key); hmac.put(msg); auto digest = hmac.finish; return digest; } auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { ubyte[] kString = cast(ubyte[])("AWS4" ~ key); auto kDate = sign(kString, cast(ubyte[])dateStamp); auto kRegion = sign(kDate, cast(ubyte[])regionName); auto kService = sign(kRegion, cast(ubyte[])serviceName); auto kSigning = sign(kService, cast(ubyte[])"aws4_request"); return kSigning; } auto getCanonicalRequest(string canonicalURI, string canonicalQueryString, string canonicalHeaderString, string signedHeaders) { string payloadHash = sha256Of("").toHexString.toLower; string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ signedHeaders ~ "\n" ~ payloadHash; } this() { } } I need to set all variables by defaults values from "public" and all needed by function "getCanonicalRequest". But if i will use that class to build another should i set defaults again? If yes is there some solution for it? //holo By the looks, I'm guessing you do not have much experience when it comes to OOP. I think you are wanting something a bit closer to: import std.typecons : tuple, TypeTuple; interface Credential { string encode(); } class SigV4 : Credential { this() { } string encode() { } private: } TypeTuple!(string, string) AWSKeys() { import std.process; return tuple(environment.get("AWS_ACCESS_KEY"), environment.get("AWS_SECRET_KEY")); }
Class, constructor and inherance.
Hello I'm trying to write my first class. I want to use it as module and build anothers on top of it. I read that default functions attributes are not inherited. Is it that same for constructor? This is how my class (not finished) is looking right now: class credential { auto accessKey = environment.get["AWS_ACCESS_KEY"]; auto secretKey = environment.get["AWS_SECRET_KEY"]; } class sigv4 : credential { public: string method; string service; string host; string region; string endpoint; string request_parameters; string payload; private: const algorithm = "AWS4-HMAC-SHA256"; auto currentClock = Clock.currTime(UTC()); auto currentDate = cast(Date)currentClock; auto curDateStr = currentDate.toISOString; auto currentTime = cast(TimeOfDay)currentClock; auto curTimeStr = currentTime.toISOString; auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z"; auto hmac_sha256(ubyte[] key, ubyte[] msg) { auto hmac = hmac!SHA256(key); hmac.put(msg); auto digest = hmac.finish; return digest; } auto getSignatureKey(string key, string dateStamp, string regionName, string serviceName) { ubyte[] kString = cast(ubyte[])("AWS4" ~ key); auto kDate = sign(kString, cast(ubyte[])dateStamp); auto kRegion = sign(kDate, cast(ubyte[])regionName); auto kService = sign(kRegion, cast(ubyte[])serviceName); auto kSigning = sign(kService, cast(ubyte[])"aws4_request"); return kSigning; } auto getCanonicalRequest(string canonicalURI, string canonicalQueryString, string canonicalHeaderString, string signedHeaders) { string payloadHash = sha256Of("").toHexString.toLower; string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ signedHeaders ~ "\n" ~ payloadHash; } this() { } } I need to set all variables by defaults values from "public" and all needed by function "getCanonicalRequest". But if i will use that class to build another should i set defaults again? If yes is there some solution for it? //holo