Smalltalk referring to classes that are not yet defined - smalltalk

I want to be able to write code like this:
MyObject subclass: #A instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1'.
A subclass: #B instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1'.
without running each line seperately.
When I try to do this I get an error saying that A isn't declared, even if it will be declared by the time the second line will be reached.
Is there a way to overcome this?

For deferred lookups of classes, you have to look up the class in the dictionary of globals, called Smalltalk (try to inspect and browse it). You can use accessors like classNamed: or at: to look up a name that might not be defined yet when the whole expression that you want to evaluate is compiled.
MyObject subclass: #A instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1'.
(Smalltalk classNamed: #A) subclass: #B instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1'.

Some dialects support the asClass message on Symbol, allowing you to do:
MyObject subclass: #A instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1'.
#A asClasss subclass: #B instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CAT1

Related

IN() function failure

Can somebody please help me to understand why the IN() function does not work in any of the below attempts?
DECLARE #Company VARCHAR(50) = ('''ABC''' + ', ' + '''DEF''' + ', ' + '''VEG''' + ', ' + '''HIJ''') --+ WNY, VEG''')
PRINT #Company
PRINT IIF('VEG' IN (#Company), 'TRUE', 'FALSE');
DECLARE #Company2 VARCHAR(50) = ('''ABC, DEF, VEG, HIJ''')
PRINT #Company2
PRINT IIF('VEG' IN (#Company2), 'TRUE', 'FAL
Tried running the command as presented and both IIF()s return false.

Where is annotation stored in ir tree for backing field?

Where is annotation stored in ir tree? is it in backing field descriptor?
I have
#Deprecated("")
val DEPRECATED_STATIC_FIELD = "deprecated field"
ir tree is below
PROPERTY name:DEPRECATED_STATIC_FIELD visibility:public modality:FINAL [val]
annotations:
Deprecated(message = '', replaceWith = <null>, level = <null>)
FIELD PROPERTY_BACKING_FIELD name:DEPRECATED_STATIC_FIELD type:kotlin.String visibility:private [final,static]
EXPRESSION_BODY
CONST String type=kotlin.String value="deprecated field"
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-DEPRECATED_STATIC_FIELD> visibility:public modality:FINAL <> () returnType:kotlin.String
correspondingProperty: PROPERTY name:DEPRECATED_STATIC_FIELD visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-DEPRECATED_STATIC_FIELD> (): kotlin.String declared in deprecated'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:DEPRECATED_STATIC_FIELD type:kotlin.String visibility:private [final,static]' type=kotlin.String origin=null
why is it not stored in backing field?
I have also seen it is stored in ir tree backing field:
PROPERTY name:g visibility:public modality:FINAL [var]
FIELD PROPERTY_BACKING_FIELD name:g type:kotlin.Int visibility:private [static]
annotations:
JsProperty(name = <null>, namespace = <null>)
EXPRESSION_BODY
CONST Int type=kotlin.Int value=10
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-g> visibility:public modality:FINAL <> () returnType:kotlin.Int
correspondingProperty: PROPERTY name:g visibility:public modality:FINAL [var]
BLOCK_BODY
how should I decide where it is stored? Thanks

Remove html tags from a column

I have the a column in my table which stores a paragraph like below :
<p>I like it.</p>this is my job.<main>current.</main>
I want to remove the tags <p>, </p>, and and all tags between < and >.
So my expected output will be like below :
I like it. this is my job. current.
please try this
DECLARE #txt NVARCHAR(MAX) = '<p>I like it.</p>this is my job.<main>current.</main>'
SELECT x.value('.', 'NVARCHAR(MAX)') FROM ( SELECT x =
CAST(REPLACE(REPLACE(#txt, '>', '/>'), '</', '<') AS XML) ) r
this will help to remove all tags
UPDATE: Samir's answer is better than mine as it can deal with html-crap
(as long as there is no < or > as normal content :-)
You can try this:
If your string is valid XML (meaning XHTML) you might go this route:
DECLARE #yourString NVARCHAR(100)=N'<p>I like it.</p>this is my job.<main>current.</main>';
SELECT CAST(#yourString AS XML).value('.','nvarchar(max)');
returns
I like it.this is my job.current.
Using . as the XPath will return the whole content as is...
Any invalid XML (very likely with simple html) will break this...
You can use giant REPLACE() :
SELECT REPLACE(REPLACE(REPLACE(REPLACE(col, '<p>', ''), '</p>', ''), '<main>, ''), '</main>', '')
If you are working the latest SQL version then this will be easy to write using TRANSLATE() :
SELECT TRANSLATE(col, '<p></p><main></main>', '')
If u want remove tags when select, you can do a normal SELECT and clear string:
SELECT column FROM my_table;
$value = $row["column"];
$value_replaced = str_replace('<p>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('</p>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('<main>', '', $value);
$value = $value_replaced;
$value_replaced = str_replace('</main>', '', $value);

How to append data to a JSON object during a select?

I'm in the progress of migrating data from an old system. I have some boolean columns, which can be True, False or Null. Each column has a certain meaning. In the new database, I use a JSON Data object. What I would like to achieve is this:
OldTable:
ValueA, ValueB, ValueC, ValueD
Null , True , False , True
I create now Json data using a select on my old table and FOR JSON to get the Json object. The object should look something like this:
{
myObject: {
data: "valueB, ValueD"
}
}
My problem is the appending the values to the same "data" field.
So right now I can only do it with single values like this:
SELECT CASE WHEN ValueA == True THEN 'ValueA' END 'myObject.data',
CASE WHEN ValueB == True THEN 'ValueB' END 'myObject.data'
FROM myLegacyTable FOR JSON Path
This would obviously overwrite, what ever is in myObject.data, whenever both values are true. JSON_MODIFY seems not to be an option, as I'm not working on an existing Json object, but creating a new one. Maybe someone else has an idea?
You can just build your json string with a CASE WHEN. If you want to handle a variable number of columns you'll probably need dynamic TSQL.
This is a simple static version that should do the job:
declare #tmp table(ValueA bit, ValueB bit, ValueC bit, ValueD bit)
insert into #tmp values (null, 1 ,0 , 1)
SELECT JSON_QUERY('{"data":"' +
stuff(
case when ValueA = 1 then ',ValueA' else '' end
+ case when ValueB = 1 then ',ValueB' else '' end
+ case when ValueC = 1 then ',ValueC' else '' end
+ case when ValueD = 1 then ',ValueD' else '' end
,1,1,'')
+ '"}') as myObject
FROM #tmp FOR JSON Path, without_array_wrapper
Result:
I don't know how your source data is really stored but here is an example of what you need to do if this was all in SQL Server
data.property is not seperate items so don't split it into columns. It's just a single concatenated string. So concatenate everything up and remove the trailing comma.
DECLARE #MyTable TABLE (
RowID INT,
ValueA VARCHAR(5),
ValueB VARCHAR(5),
ValueC VARCHAR(5),
ValueD VARCHAR(5)
)
INSERT INTO #MyTable (RowID,ValueA,ValueB,ValueC,ValueD) VALUES
(1,NULL,'True','False','True'),
(2,'False',NULL,'True','True'),
(3,NULL,'False',NULL,NULL)
SELECT
ISNULL(
RTRIM(REVERSE(STUFF(REVERSE
(
CASE WHEN ValueA='True' THEN 'ValueA, ' ELSE '' END +
CASE WHEN ValueB='True' THEN 'ValueB, ' ELSE '' END +
CASE WHEN ValueC='True' THEN 'ValueC, ' ELSE '' END +
CASE WHEN ValueD='True' THEN 'ValueD, ' ELSE '' END
), 2, 1, ''))),'') AS 'myObject.data'
FROM #MyTable
FOR JSON Path
The huge construct required to remove trailing , is from here:
Remove the last character in a string in T-SQL?
Result:
[
{
"myObject": {
"data": "ValueB, ValueD"
}
},
{
"myObject": {
"data": "ValueC, ValueD"
}
},
{
"myObject": {
"data": ""
}
}
]

Excluding Data from SQL Results based on DATE

I have the following query built: My problem is that if I get a date that is past today's date in the policy_exp_date I need to exclude everything that is insplans or clientplans related and still return everything else specified.
To summarize: If Policy_Exp_DATE > TODAY then pull * else exclude insplans.* or clientplans.*
select clients.CLIENT_ID_1 as SourceMRN,
'' AS HMOMEMBER,
'' as IDXMRN,
replace (clients.CLIENT_ID_2,'-','') as PatientSSN,
clients.LAST_NAME as LASTNAME,
clients.FIRST_NAME as FIRSTNAME,
clients.MIDDLE_NAME as MIDDLENAME,
'' as PTMothersMaiden,
convert (varchar,clients.BIRTH_DATE,112) as DOB,
clients.sex as GENDER,
'' as PTNICKNAME,
'' as RACE,
clients.ADDRESS_1,
clients.ADDRESS_2,
clients.CITY,
clients.STATE,
clients.ZIP_CODE,
'' as FLD18,
'' as FLD19,
clients.PHONE_1 as PTHOMEPHONE,
'' as PTCELL,
'' as PTEMAIL,
'' as PTDAYPHONE,
(case WHEN [CLIENTS].LANGUAGE_ID LIKE '0' THEN 'ENGLISH'
when [clients].LANGUAGE_ID like '1' then 'SPANISH' END) as LANGUAGE,
'' as MaritalStatus,
'' as Religion,
'' as Ethnicity,
'' as PtExpDate,
'' as PtExpIndex,
'' as LASTUPDATEDATE,
convert (varchar,clientlog.FNDATE,112) as LASTUPDATEDATE,
'' as PCPNAME,
'' as VIP,
'' as FLD33,
'' as PREFCONTACT,
'' as FLD35,
'' as GUARANTORNAME,
'' AS GUARADDRESS1,
'' AS GUARADDRESS2,
'' AS GUARCITY,
'' AS GUARSTATE,
'' AS GUARZIP,
'' AS GUARHOMEPHONE,
'' AS GUARWORKPHONE,
'' AS GUARRELATIONSHIP,
'' as GUARSSN,
'' as GUAREMPNAME,
'' as FLD47,
'' AS GUAREMPADDRESS1,
'' as GUAREMPADDRESS2,
'' as GUAREMPCITY,
'' AS GUAREMPSTATE,
'' AS GUAREMPZIP,
'' AS GUAREMPPHONE,
'' AS GUAREMPSTATUS,
'' AS FLD55,
'' AS FLD56,
'' AS FLD57,
'' AS FLD58,
'' AS FLD59,
'' AS FLD60,
'' AS FLD61,
'' AS FLD62,
'' AS FLD63,
'' AS FLD64,
'' AS FLD65,
insplans.DESCRIPTION_UPPER AS FINANCIAL_CLASS,
'' as PAYERID#,
insplans.DESCRIPTION_UPPER as PAYERNAME,
'' as PAYERADDRESS2,
'' AS PAYERCITY,
'' AS PAYERSTATE,
'' AS PAYERZIP,
'' AS PAYERCONTACTNBR,
clientplans.GROUP_NO AS GROUPNUMBER,
convert (varchar,clientplans.START_DATE,112) as POLICY_EFF_DATE,
convert (varchar,clientplans.END_DATE,112) as POLICY_EXP_DATE,
clientplans.SEQUENCE_NUM,
(clients.LAST_NAME +'^' + clients.FIRST_NAME)as INSURED_NAME,
'' as INSURED_DOB,
'' AS INSURED_ADD1,
'' AS INSURED_ADD2,
'' AS INSURED_CITY,
'' AS INSURED_STATE,
'' AS INSURED_ZIP,
'' AS INSURED_PLAN_NBR,
clientplans.POLICY_NO AS POLICY_NBR,
'' AS INSURED_GENDER,
'' AS INSURED_HOMEPHONE,
'' AS INSURED_EMP_NAME,
'' AS INSURED_RELATION,
'' AS ACCIDENT_DATE,
'' AS ACCIDENT_CODE,
'' AS ACCIDENT_STATE,
'' AS FLD94,
'' AS CLINICAL_REMINDER,
'' AS APPT_REMINDER,
'' AS INS_INST,
'' AS SET_ID,
'' AS COPAY,
'CC' AS SOURCE_PREFIX
FROM project.dbo.CLIENTS
join CLIENTPLANS
on clients.RECORD_ID = clientplans.CLIENT_ID
join INSPLANS
on insplans.RECORD_ID = clientplans.PLAN_ID
join (SELECT MAX(fndate) FNDATE,client_id
from CLIENTLOG
group by CLIENT_ID)CLIENTLOG
on clientlog.CLIENT_ID = clients.RECORD_ID
where clients.RECORD_ID = clientplans.CLIENT_ID
Would something like work?
FROM project.dbo.CLIENTS
join (SELECT MAX(fndate) FNDATE,client_id
from CLIENTLOG
group by CLIENT_ID)CLIENTLOG
on clientlog.CLIENT_ID = clients.RECORD_ID
Left Outer join CLIENTPLANS
on clients.RECORD_ID = clientplans.CLIENT_ID
And clientplans.END_DATE > GetDate()
Left Outer join INSPLANS
on clientplans.PLAN_ID = insplans.RECORD_ID
Also make sure to remove the where clause or you will be removing a lot of the records.