October 12, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | @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, kDate); auto kService = sign(serviceName.representation, kRegion); auto kSigning = sign("aws4_request".representation, kService); return kSigning; } auto getCanonicalRequest(string canonicalURI, string canonicalQueryString, string canonicalHeadersString, string signedHeaders) { string payloadHash = sha256Of(payload).toHexString.toLower; string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ signedHeaders ~ "\n" ~ payloadHash; return canonicalRequest; } } void main() { sigv4 sig = new sigv4(); writeln(sig.go()); } 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? |
October 13, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to holo | 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, kDate);
> auto kService = sign(serviceName.representation, kRegion);
> auto kSigning = sign("aws4_request".representation, kService);
>
> return kSigning;
> }
>
>
> auto getCanonicalRequest(string canonicalURI, string
> canonicalQueryString, string canonicalHeadersString, string signedHeaders)
> {
> string payloadHash = sha256Of(payload).toHexString.toLower;
> string canonicalRequest = method ~ "\n" ~ canonicalURI ~
> "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~
> signedHeaders ~ "\n" ~ payloadHash;
> return canonicalRequest;
> }
> }
>
> void main()
> {
> sigv4 sig = new sigv4();
> writeln(sig.go());
> }
>
> 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();
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.
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.
|
October 13, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | 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 = sign(dateStamp.representation, kString); >> auto kRegion = sign(regionName.representation, kDate); >> auto kService = sign(serviceName.representation, kRegion); >> auto kSigning = sign("aws4_request".representation, kService); >> >> return kSigning; >> } >> >> >> auto getCanonicalRequest(string canonicalURI, string >> canonicalQueryString, string canonicalHeadersString, string signedHeaders) >> { >> string payloadHash = sha256Of(payload).toHexString.toLower; >> string canonicalRequest = method ~ "\n" ~ canonicalURI ~ >> "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ >> signedHeaders ~ "\n" ~ payloadHash; >> return canonicalRequest; >> } >> } >> >> void main() >> { >> sigv4 sig = new sigv4(); >> writeln(sig.go()); >> } >> >> 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. > > 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? 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). |
October 14, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to holo | 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 = sign(dateStamp.representation, kString); >>> auto kRegion = sign(regionName.representation, kDate); >>> auto kService = sign(serviceName.representation, kRegion); >>> auto kSigning = sign("aws4_request".representation, >>> kService); >>> >>> return kSigning; >>> } >>> >>> >>> auto getCanonicalRequest(string canonicalURI, string >>> canonicalQueryString, string canonicalHeadersString, string >>> signedHeaders) >>> { >>> string payloadHash = sha256Of(payload).toHexString.toLower; >>> string canonicalRequest = method ~ "\n" ~ canonicalURI ~ >>> "\n" ~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ >>> signedHeaders ~ "\n" ~ payloadHash; >>> return canonicalRequest; >>> } >>> } >>> >>> void main() >>> { >>> sigv4 sig = new sigv4(); >>> writeln(sig.go()); >>> } >>> >>> 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. > 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. 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. Also classes start with a capital letter, like Credential or SigV4. And D prefers camal casing aka requestParameters for variables/functions. |
October 14, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | >>>> >>>> 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 |
October 15, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to holo | 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)
|
October 15, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | >
> 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.
|
October 15, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to holo | 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.
|
October 15, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | 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]$ |
October 15, 2015 Re: Class, constructor and inherance. | ||||
---|---|---|---|---|
| ||||
Posted in reply to holo | 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.
|
Copyright © 1999-2021 by the D Language Foundation